Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/iostream.cfa

    r7cfef0d r4f37255  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Aug 24 08:31:35 2020
    13 // Update Count     : 1130
     12// Last Modified On : Sat Jul 13 08:07:59 2019
     13// Update Count     : 821
    1414//
    1515
    1616#include "iostream.hfa"
    1717
     18extern "C" {
    1819#include <stdio.h>
    1920#include <stdbool.h>                                                                    // true/false
    20 #include <stdint.h>                                                                             // UINT64_MAX
    21 #include <float.h>                                                                              // DBL_DIG, LDBL_DIG
    22 #include <complex.h>                                                                    // creal, cimag
    23 //#include <string.h>                                                                   // strlen, strcmp, memcpy
    24 extern "C" {
     21//#include <string.h>                                                                   // strlen, strcmp
    2522extern size_t strlen (const char *__s) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1)));
    2623extern int strcmp (const char *__s1, const char *__s2) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2)));
    2724extern char *strcpy (char *__restrict __dest, const char *__restrict __src) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
    2825extern void *memcpy (void *__restrict __dest, const void *__restrict __src, size_t __n) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
     26#include <float.h>                                                                              // DBL_DIG, LDBL_DIG
     27#include <math.h>                                                                               // isfinite
     28#include <complex.h>                                                                    // creal, cimag
    2929} // extern "C"
    3030
    31 #include "math.hfa"                                                                             // isfinite, floor, ceiling_div
    32 #include "bitmanip.hfa"                                                                 // high1
    33 
    34 
    35 // *********************************** ostream ***********************************
     31
     32//*********************************** ostream ***********************************
    3633
    3734
    3835forall( dtype ostype | ostream( ostype ) ) {
     36        ostype & ?|?( ostype & os, zero_t ) {
     37                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     38                fmt( os, "%d", 0n );
     39                return os;
     40        } // ?|?
     41        void ?|?( ostype & os, zero_t z ) {
     42                (ostype &)(os | z); ends( os );
     43        } // ?|?
     44
     45        ostype & ?|?( ostype & os, one_t ) {
     46                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     47                fmt( os, "%d", 1n );
     48                return os;
     49        } // ?|?
     50        void ?|?( ostype & os, one_t o ) {
     51                (ostype &)(os | o); ends( os );
     52        } // ?|?
     53
    3954        ostype & ?|?( ostype & os, bool b ) {
    40                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     55                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    4156                fmt( os, "%s", b ? "true" : "false" );
    4257                return os;
     
    4863        ostype & ?|?( ostype & os, char c ) {
    4964                fmt( os, "%c", c );
    50                 if ( c == '\n' ) $setNL( os, true );
     65                if ( c == '\n' ) setNL( os, true );
    5166                return sepOff( os );
    5267        } // ?|?
     
    5671
    5772        ostype & ?|?( ostype & os, signed char sc ) {
    58                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     73                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    5974                fmt( os, "%hhd", sc );
    6075                return os;
     
    6580
    6681        ostype & ?|?( ostype & os, unsigned char usc ) {
    67                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     82                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    6883                fmt( os, "%hhu", usc );
    6984                return os;
     
    7489
    7590        ostype & ?|?( ostype & os, short int si ) {
    76                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     91                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    7792                fmt( os, "%hd", si );
    7893                return os;
     
    8398
    8499        ostype & ?|?( ostype & os, unsigned short int usi ) {
    85                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     100                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    86101                fmt( os, "%hu", usi );
    87102                return os;
     
    92107
    93108        ostype & ?|?( ostype & os, int i ) {
    94                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     109                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    95110                fmt( os, "%d", i );
    96111                return os;
     
    101116
    102117        ostype & ?|?( ostype & os, unsigned int ui ) {
    103                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     118                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    104119                fmt( os, "%u", ui );
    105120                return os;
     
    110125
    111126        ostype & ?|?( ostype & os, long int li ) {
    112                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     127                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    113128                fmt( os, "%ld", li );
    114129                return os;
     
    119134
    120135        ostype & ?|?( ostype & os, unsigned long int uli ) {
    121                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     136                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    122137                fmt( os, "%lu", uli );
    123138                return os;
     
    128143
    129144        ostype & ?|?( ostype & os, long long int lli ) {
    130                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     145                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    131146                fmt( os, "%lld", lli );
    132147                return os;
     
    137152
    138153        ostype & ?|?( ostype & os, unsigned long long int ulli ) {
    139                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     154                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    140155                fmt( os, "%llu", ulli );
    141156                return os;
     
    144159                (ostype &)(os | ulli); ends( os );
    145160        } // ?|?
    146 
    147 #if defined( __SIZEOF_INT128__ )
    148         //      UINT64_MAX 18_446_744_073_709_551_615_ULL
    149         #define P10_UINT64 10_000_000_000_000_000_000_ULL       // 19 zeroes
    150 
    151         static inline void base10_128( ostype & os, unsigned int128 val ) {
    152 #if defined(__GNUC__) && __GNUC_PREREQ(7,0)                             // gcc version >= 7
    153                 if ( val > P10_UINT64 ) {
    154 #else
    155                 if ( (uint64_t)(val >> 64) != 0 || (uint64_t)val > P10_UINT64 ) { // patch gcc 5 & 6 -O3 bug
    156 #endif // __GNUC_PREREQ(7,0)
    157                         base10_128( os, val / P10_UINT64 );                     // recursive
    158                         fmt( os, "%.19lu", (uint64_t)(val % P10_UINT64) );
    159                 } else {
    160                         fmt( os, "%lu", (uint64_t)val );
    161                 } // if
    162         } // base10_128
    163 
    164         static inline void base10_128( ostype & os, int128 val ) {
    165                 if ( val < 0 ) {
    166                         fmt( os, "-" );                                                         // leading negative sign
    167                         val = -val;
    168                 } // if
    169                 base10_128( os, (unsigned int128)val );                 // print zero/positive value
    170         } // base10_128
    171 
    172         ostype & ?|?( ostype & os, int128 llli ) {
    173                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    174                 base10_128( os, llli );
    175                 return os;
    176         } // ?|?
    177         void & ?|?( ostype & os, int128 llli ) {
    178                 (ostype &)(os | llli); ends( os );
    179         } // ?|?
    180 
    181         ostype & ?|?( ostype & os, unsigned int128 ullli ) {
    182                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    183                 base10_128( os, ullli );
    184                 return os;
    185         } // ?|?
    186         void & ?|?( ostype & os, unsigned int128 ullli ) {
    187                 (ostype &)(os | ullli); ends( os );
    188         } // ?|?
    189 #endif // __SIZEOF_INT128__
    190161
    191162        #define PrintWithDP( os, format, val, ... ) \
     
    204175
    205176        ostype & ?|?( ostype & os, float f ) {
    206                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     177                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    207178                PrintWithDP( os, "%g", f );
    208179                return os;
     
    213184
    214185        ostype & ?|?( ostype & os, double d ) {
    215                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     186                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    216187                PrintWithDP( os, "%.*lg", d, DBL_DIG );
    217188                return os;
     
    222193
    223194        ostype & ?|?( ostype & os, long double ld ) {
    224                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     195                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    225196                PrintWithDP( os, "%.*Lg", ld, LDBL_DIG );
    226197                return os;
     
    231202
    232203        ostype & ?|?( ostype & os, float _Complex fc ) {
    233                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     204                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    234205//              os | crealf( fc ) | nonl;
    235206                PrintWithDP( os, "%g", crealf( fc ) );
     
    243214
    244215        ostype & ?|?( ostype & os, double _Complex dc ) {
    245                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     216                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    246217//              os | creal( dc ) | nonl;
    247218                PrintWithDP( os, "%.*lg", creal( dc ), DBL_DIG );
     
    255226
    256227        ostype & ?|?( ostype & os, long double _Complex ldc ) {
    257                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     228                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    258229//              os | creall( ldc ) || nonl;
    259230                PrintWithDP( os, "%.*Lg", creall( ldc ), LDBL_DIG );
     
    266237        } // ?|?
    267238
    268         ostype & ?|?( ostype & os, const char str[] ) {
     239        ostype & ?|?( ostype & os, const char * str ) {
    269240                enum { Open = 1, Close, OpenClose };
    270241                static const unsigned char mask[256] @= {
     
    286257                // first character IS NOT spacing or closing punctuation => add left separator
    287258                unsigned char ch = str[0];                                              // must make unsigned
    288                 if ( $sepPrt( os ) && mask[ ch ] != Close && mask[ ch ] != OpenClose ) {
    289                         fmt( os, "%s", $sepGetCur( os ) );
     259                if ( sepPrt( os ) && mask[ ch ] != Close && mask[ ch ] != OpenClose ) {
     260                        fmt( os, "%s", sepGetCur( os ) );
    290261                } // if
    291262
    292263                // if string starts line, must reset to determine open state because separator is off
    293                 $sepReset( os );                                                                // reset separator
     264                sepReset( os );                                                                 // reset separator
    294265
    295266                // last character IS spacing or opening punctuation => turn off separator for next item
    296267                size_t len = strlen( str );
    297268                ch = str[len - 1];                                                              // must make unsigned
    298                 if ( $sepPrt( os ) && mask[ ch ] != Open && mask[ ch ] != OpenClose ) {
     269                if ( sepPrt( os ) && mask[ ch ] != Open && mask[ ch ] != OpenClose ) {
    299270                        sepOn( os );
    300271                } else {
    301272                        sepOff( os );
    302273                } // if
    303                 if ( ch == '\n' ) $setNL( os, true );                   // check *AFTER* $sepPrt call above as it resets NL flag
     274                if ( ch == '\n' ) setNL( os, true );                    // check *AFTER* sepPrt call above as it resets NL flag
    304275                return write( os, str, len );
    305276        } // ?|?
    306 
    307         void ?|?( ostype & os, const char str[] ) {
     277        void ?|?( ostype & os, const char * str ) {
    308278                (ostype &)(os | str); ends( os );
    309279        } // ?|?
    310280
    311281//      ostype & ?|?( ostype & os, const char16_t * str ) {
    312 //              if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     282//              if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    313283//              fmt( os, "%ls", str );
    314284//              return os;
     
    317287// #if ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 ) // char32_t == wchar_t => ambiguous
    318288//      ostype & ?|?( ostype & os, const char32_t * str ) {
    319 //              if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     289//              if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    320290//              fmt( os, "%ls", str );
    321291//              return os;
     
    324294
    325295//      ostype & ?|?( ostype & os, const wchar_t * str ) {
    326 //              if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     296//              if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    327297//              fmt( os, "%ls", str );
    328298//              return os;
     
    330300
    331301        ostype & ?|?( ostype & os, const void * p ) {
    332                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     302                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    333303                fmt( os, "%p", p );
    334304                return os;
     
    345315        void ?|?( ostype & os, ostype & (* manip)( ostype & ) ) {
    346316                (ostype &)(manip( os ));
    347                 if ( $getPrt( os ) ) ends( os );                                // something printed ?
    348                 $setPrt( os, false );                                                   // turn off
     317                if ( getPrt( os ) ) ends( os );                                 // something printed ?
     318                setPrt( os, false );                                                    // turn off
    349319        } // ?|?
    350320
     
    359329        ostype & nl( ostype & os ) {
    360330                (ostype &)(os | '\n');
    361                 $setPrt( os, false );                                                   // turn off
    362                 $setNL( os, true );
     331                setPrt( os, false );                                                    // turn off
     332                setNL( os, true );
    363333                flush( os );
    364334                return sepOff( os );                                                    // prepare for next line
     
    366336
    367337        ostype & nonl( ostype & os ) {
    368                 $setPrt( os, false );                                                   // turn off
     338                setPrt( os, false );                                                    // turn off
    369339                return os;
    370340        } // nonl
     
    405375        ostype & ?|?( ostype & os, T arg, Params rest ) {
    406376                (ostype &)(os | arg);                                                   // print first argument
    407                 $sepSetCur( os, sepGetTuple( os ) );                    // switch to tuple separator
     377                sepSetCur( os, sepGetTuple( os ) );                             // switch to tuple separator
    408378                (ostype &)(os | rest);                                                  // print remaining arguments
    409                 $sepSetCur( os, sepGet( os ) );                                 // switch to regular separator
     379                sepSetCur( os, sepGet( os ) );                                  // switch to regular separator
    410380                return os;
    411381        } // ?|?
     
    413383                // (ostype &)(?|?( os, arg, rest )); ends( os );
    414384                (ostype &)(os | arg);                                                   // print first argument
    415                 $sepSetCur( os, sepGetTuple( os ) );                    // switch to tuple separator
     385                sepSetCur( os, sepGetTuple( os ) );                             // switch to tuple separator
    416386                (ostype &)(os | rest);                                                  // print remaining arguments
    417                 $sepSetCur( os, sepGet( os ) );                                 // switch to regular separator
     387                sepSetCur( os, sepGet( os ) );                                  // switch to regular separator
    418388                ends( os );
    419389        } // ?|?
     
    433403} // distribution
    434404
    435 // *********************************** manipulators ***********************************
    436 
    437 // *********************************** integral ***********************************
     405//*********************************** manipulators ***********************************
     406
     407//*********************************** integral ***********************************
    438408
    439409static const char * shortbin[] = { "0", "1", "10", "11", "100", "101", "110", "111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111" };
     
    441411
    442412// Default prefix for non-decimal prints is 0b, 0, 0x.
    443 #define IntegralFMTImpl( T, IFMTNP, IFMTP ) \
     413#define IntegralFMTImpl( T, CODE, IFMTNP, IFMTP ) \
    444414forall( dtype ostype | ostream( ostype ) ) { \
    445415        ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \
    446                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) ); \
     416                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) ); \
    447417\
    448418                if ( f.base == 'b' || f.base == 'B' ) {                 /* bespoke binary format */ \
    449                         int bits = high1( f.val );                                      /* position of most significant bit */ \
    450                         if ( bits == 0 ) bits = 1;                                      /* 0 value => force one bit to print */ \
    451                         int spaces; \
     419                        int bits;                                                                                                       \
     420                        if ( f.val == (T){0} ) bits = 1;                        /* force at least one bit to print */ \
     421                        else bits = sizeof(long long int) * 8 - __builtin_clzll( f.val ); /* position of most significant bit */ \
     422                        bits = bits > sizeof(f.val) * 8 ? sizeof(f.val) * 8 : bits; \
     423                        int spaces = f.wd - bits;                                       /* can be negative */ \
     424                        if ( ! f.flags.nobsdp ) { spaces -= 2; }        /* base prefix takes space */ \
     425                        /* printf( "%d %d\n", bits, spaces ); */ \
    452426                        if ( ! f.flags.left ) {                                         /* right justified ? */ \
    453427                                /* Note, base prefix then zero padding or spacing then prefix. */ \
    454                                 if ( f.flags.pc ) { \
    455                                         spaces = f.wd - f.pc; \
    456                                         if ( ! f.flags.nobsdp ) { spaces -= 2; } /* base prefix takes space */ \
     428                                if ( f.flags.pad0 || f.flags.pc ) { \
     429                                        if ( ! f.flags.nobsdp ) { fmt( os, "0%c", f.base ); } \
     430                                        if ( f.flags.pc ) spaces = f.pc - bits; \
     431                                        if ( spaces > 0 ) fmt( os, "%0*d", spaces, 0 ); /* zero pad */ \
     432                                } else { \
    457433                                        if ( spaces > 0 ) fmt( os, "%*s", spaces, " " ); /* space pad */ \
    458434                                        if ( ! f.flags.nobsdp ) { fmt( os, "0%c", f.base ); } \
    459                                         spaces = f.pc - bits; \
    460                                         if ( spaces > 0 ) fmt( os, "%0*d", spaces, 0 ); /* zero pad */ \
    461                                 } else { \
    462                                         spaces = f.wd - bits; \
    463                                         if ( ! f.flags.nobsdp ) { spaces -= 2; } /* base prefix takes space */ \
    464                                         if ( f.flags.pad0 ) { \
    465                                                 if ( ! f.flags.nobsdp ) { fmt( os, "0%c", f.base ); } \
    466                                                 if ( spaces > 0 ) fmt( os, "%0*d", spaces, 0 ); /* zero pad */ \
    467                                         } else { \
    468                                                 if ( spaces > 0 ) fmt( os, "%*s", spaces, " " ); /* space pad */ \
    469                                                 if ( ! f.flags.nobsdp ) { fmt( os, "0%c", f.base ); } \
    470                                         } /* if */ \
    471435                                } /* if */ \
    472                         } else { \
    473                                 if ( ! f.flags.nobsdp ) fmt( os, "0%c", f.base ); \
    474                                 if ( f.flags.pc ) { \
    475                                         spaces = f.pc - bits; \
    476                                         if ( spaces > 0 ) fmt( os, "%0*d", spaces, 0 ); /* zero pad */ \
    477                                         spaces = f.wd - f.pc; \
    478                                 } else { /* pad0 flag ignored with left flag */ \
    479                                         spaces = f.wd - bits; \
    480                                 } /* if */ \
    481                                 if ( ! f.flags.nobsdp ) { spaces -= 2; } /* base prefix takes space */ \
     436                        } else if ( ! f.flags.nobsdp ) { \
     437                                fmt( os, "0%c", f.base ); \
    482438                        } /* if */ \
    483                         int shift = floor( bits - 1, 4 ); \
     439                        int shift = (bits - 1) / 4 * 4; /* floor( bits - 1, 4 ) */ \
    484440                        typeof( f.val ) temp = f.val; \
    485441                        fmt( os, "%s", shortbin[(temp >> shift) & 0xf] ); \
     
    492448                        if ( f.flags.left && spaces > 0 ) fmt( os, "%*s", spaces, " " ); \
    493449                        return os; \
    494                 } /* if */ \
     450                } /* if  */ \
    495451\
    496452                char fmtstr[sizeof(IFMTP)];                                             /* sizeof includes '\0' */ \
     
    502458                if ( ! f.flags.nobsdp ) { fmtstr[star] = '#'; star -= 1; } \
    503459                if ( f.flags.left ) { fmtstr[star] = '-'; star -= 1; } \
    504                 if ( f.flags.sign ) { fmtstr[star] = '+'; star -= 1; } \
     460                if ( f.flags.sign && f.base == CODE ) { fmtstr[star] = '+'; star -= 1; } \
    505461                if ( f.flags.pad0 && ! f.flags.pc ) { fmtstr[star] = '0'; star -= 1; } \
    506462                fmtstr[star] = '%'; \
    507463\
    508464                if ( ! f.flags.pc ) {                                                   /* no precision */ \
     465                        /* printf( "%s\n", &fmtstr[star] ); */ \
    509466                        fmtstr[sizeof(IFMTNP)-2] = f.base;                      /* sizeof includes '\0' */ \
    510                         /* printf( "%s %c\n", &fmtstr[star], f.base ); */ \
    511467                        fmt( os, &fmtstr[star], f.wd, f.val ); \
    512468                } else {                                                                                /* precision */ \
    513469                        fmtstr[sizeof(IFMTP)-2] = f.base;                       /* sizeof includes '\0' */ \
    514                         /* printf( "%s %c\n", &fmtstr[star], f.base ); */ \
     470                        /* printf( "%s\n", &fmtstr[star] ); */ \
    515471                        fmt( os, &fmtstr[star], f.wd, f.pc, f.val ); \
    516472                } /* if */ \
     
    520476} // distribution
    521477
    522 IntegralFMTImpl( signed char, "%    *hh ", "%    *.*hh " )
    523 IntegralFMTImpl( unsigned char, "%    *hh ", "%    *.*hh " )
    524 IntegralFMTImpl( signed short int, "%    *h ", "%    *.*h " )
    525 IntegralFMTImpl( unsigned short int, "%    *h ", "%    *.*h " )
    526 IntegralFMTImpl( signed int, "%    * ", "%    *.* " )
    527 IntegralFMTImpl( unsigned int, "%    * ", "%    *.* " )
    528 IntegralFMTImpl( signed long int, "%    *l ", "%    *.*l " )
    529 IntegralFMTImpl( unsigned long int, "%    *l ", "%    *.*l " )
    530 IntegralFMTImpl( signed long long int, "%    *ll ", "%    *.*ll " )
    531 IntegralFMTImpl( unsigned long long int, "%    *ll ", "%    *.*ll " )
    532 
    533 #if 0
    534 #if defined( __SIZEOF_INT128__ )
    535 // Default prefix for non-decimal prints is 0b, 0, 0x.
    536 #define IntegralFMTImpl128( T, SIGNED, CODE, IFMTNP, IFMTP ) \
    537 forall( dtype ostype | ostream( ostype ) ) \
    538 static void base10_128( ostype & os, _Ostream_Manip(T) f ) { \
    539         if ( f.val > UINT64_MAX ) { \
    540                 unsigned long long int lsig = f.val % P10_UINT64; \
    541                 f.val /= P10_UINT64; /* msig */ \
    542                 base10_128( os, f ); /* recursion */ \
    543                 _Ostream_Manip(unsigned long long int) fmt @= { lsig, 0, 19, 'u', { .all : 0 } }; \
    544                 fmt.flags.nobsdp = true; \
    545                 /* printf( "fmt1 %c %lld %d\n", fmt.base, fmt.val, fmt.all ); */ \
    546                 sepOff( os ); \
    547                 (ostype &)(os | fmt); \
    548         } else { \
    549                 /* printf( "fmt2 %c %lld %d\n", f.base, (unsigned long long int)f.val, f.all ); */ \
    550                 _Ostream_Manip(SIGNED long long int) fmt @= { (SIGNED long long int)f.val, f.wd, f.pc, f.base, { .all : f.all } }; \
    551                 (ostype &)(os | fmt); \
    552         } /* if */ \
    553 } /* base10_128 */ \
    554 forall( dtype ostype | ostream( ostype ) ) { \
    555         ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \
    556                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) ); \
    557 \
    558                 if ( f.base == 'b' | f.base == 'B' | f.base == 'o' | f.base == 'x' | f.base == 'X' ) { \
    559                         unsigned long long int msig = (unsigned long long int)(f.val >> 64); \
    560                         unsigned long long int lsig = (unsigned long long int)(f.val); \
    561                         _Ostream_Manip(SIGNED long long int) fmt @= { msig, f.wd, f.pc, f.base, { .all : f.all } }; \
    562                         _Ostream_Manip(unsigned long long int) fmt2 @= { lsig, 0, 0, f.base, { .all : 0 } }; \
    563                         if ( msig == 0 ) { \
    564                                 fmt.val = lsig; \
    565                                 (ostype &)(os | fmt); \
    566                         } else { \
    567                                 fmt2.flags.pad0 = fmt2.flags.nobsdp = true;     \
    568                                 if ( f.base == 'b' | f.base == 'B' ) { \
    569                                         if ( fmt.flags.pc && fmt.pc > 64 ) fmt.pc -= 64; else { fmt.flags.pc = false; fmt.pc = 0; } \
    570                                         if ( fmt.flags.left ) { \
    571                                                 fmt.flags.left = false; \
    572                                                 fmt.wd = 0; \
    573                                                 /* printf( "L %llo %llo %llo %d %d '%c' %x\n", msig, lsig, fmt.val, fmt.wd, fmt.pc, fmt.base, fmt.all ); */ \
    574                                                 fmt2.flags.left = true; \
    575                                                 int msigd = high1( msig ); \
    576                                                 fmt2.wd = f.wd - (fmt.pc > msigd ? fmt.pc : msigd); \
    577                                                 if ( ! fmt.flags.nobsdp ) fmt2.wd -= 2; /* compensate for 0b base specifier */ \
    578                                                 if ( (int)fmt2.wd < 64 ) fmt2.wd = 64; /* cast deals with negative value */ \
    579                                                 fmt2.flags.pc = true; fmt2.pc = 64; \
    580                                         } else { \
    581                                                 if ( fmt.wd > 64 ) fmt.wd -= 64; \
    582                                                 else fmt.wd = 1; \
    583                                                 /* printf( "R %llo %llo %llo %d %d '%c' %x\n", msig, lsig, fmt.val, fmt.wd, fmt.pc, fmt.base, fmt.all ); */ \
    584                                                 fmt2.wd = 64; \
    585                                         } /* if */ \
    586                                         /* printf( "C %llo %d %d '%c' %x\n", fmt2.val, fmt2.wd, fmt2.pc, fmt2.base, fmt2.all ); */ \
    587                                         (ostype &)(os | fmt | "" | fmt2); \
    588                                 } else if ( f.base == 'o' ) { \
    589                                         if ( fmt.flags.pc && fmt.pc > 22 ) fmt.pc -= 22; else { fmt.flags.pc = false; fmt.pc = 0; } \
    590                                         fmt.val = (unsigned long long int)fmt.val >> 2; \
    591                                         fmt2.val = ((msig & 0x3) << 1) + ((lsig & 0x8000000000000000U) != 0); \
    592                                         if ( fmt.flags.left ) { \
    593                                                 fmt.flags.left = false; \
    594                                                 fmt.wd = 0; \
    595                                                 /* printf( "L %llo %llo %llo %d %d '%c' %x %llo %d %d '%c' %x\n", msig, lsig, fmt.val, fmt.wd, fmt.pc, fmt.base, fmt.all, fmt2.val, fmt2.wd, fmt2.pc, fmt2.base, fmt2.all ); */ \
    596                                                 (ostype &)(os | fmt | "" | fmt2); \
    597                                                 sepOff( os ); \
    598                                                 fmt2.flags.left = true; \
    599                                                 int msigd = ceiling_div( high1( fmt.val ), 3 ); \
    600                                                 fmt2.wd = f.wd - (fmt.pc > msigd ? fmt.pc : msigd); \
    601                                                 if ( ! fmt.flags.nobsdp ) fmt2.wd -= 1; /* compensate for 0 base specifier */ \
    602                                                 if ( (int)fmt2.wd < 21 ) fmt2.wd = 21; /* cast deals with negative value */ \
    603                                                 fmt2.flags.pc = true; fmt2.pc = 21; \
    604                                         } else { \
    605                                                 if ( fmt.wd > 22 ) fmt.wd -= 22; \
    606                                                 else fmt.wd = 1; \
    607                                                 /* printf( "R %llo %llo %llo %d %d '%c' %x %llo %d %d '%c' %x\n", msig, lsig, fmt.val, fmt.wd, fmt.pc, fmt.base, fmt.all, fmt2.val, fmt2.wd, fmt2.pc, fmt2.base, fmt2.all ); */ \
    608                                                 (ostype &)(os | fmt | "" | fmt2); \
    609                                                 sepOff( os ); \
    610                                                 fmt2.wd = 21; \
    611                                         } /* if */ \
    612                                         fmt2.val = lsig & 0x7fffffffffffffffU; \
    613                                         /* printf( "\nC %llo %d %d '%c' %x\n", fmt2.val, fmt2.wd, fmt2.pc, fmt2.base, fmt2.all ); */ \
    614                                         (ostype &)(os | fmt2); \
    615                                 } else { /* f.base == 'x'  | f.base == 'X' */ \
    616                                         if ( fmt.flags.pc && fmt.pc > 16 ) fmt.pc -= 16; else { fmt.flags.pc = false; fmt.pc = 0; } \
    617                                         if ( fmt.flags.left ) { \
    618                                                 fmt.flags.left = false; \
    619                                                 fmt.wd = 0; \
    620                                                 /* printf( "L %llo %llo %llo %d %d '%c' %x\n", msig, lsig, fmt.val, fmt.wd, fmt.pc, fmt.base, fmt.all ); */ \
    621                                                 fmt2.flags.left = true; \
    622                                                 int msigd = high1( msig ); \
    623                                                 fmt2.wd = f.wd - (fmt.pc > msigd ? fmt.pc : msigd); \
    624                                                 if ( ! fmt.flags.nobsdp ) fmt2.wd -= 2; /* compensate for 0x base specifier */ \
    625                                                 if ( (int)fmt2.wd < 16 ) fmt2.wd = 16; /* cast deals with negative value */ \
    626                                                 fmt2.flags.pc = true; fmt2.pc = 16; \
    627                                         } else { \
    628                                                 if ( fmt.wd > 16 ) fmt.wd -= 16; \
    629                                                 else fmt.wd = 1; \
    630                                                 /* printf( "R %llo %llo %llo %d %d '%c' %x\n", msig, lsig, fmt.val, fmt.wd, fmt.pc, fmt.base, fmt.all ); */ \
    631                                                 fmt2.wd = 16; \
    632                                         } /* if */ \
    633                                         /* printf( "C %llo %d %d '%c' %x\n", fmt2.val, fmt2.wd, fmt2.pc, fmt2.base, fmt2.all ); */ \
    634                                         (ostype &)(os | fmt | "" | fmt2); \
    635                                 } /* if */ \
    636                         } /* if */ \
    637                 } else { \
    638                         if ( CODE == 'd' ) { \
    639                                 if ( f.val < 0 )  { fmt( os, "-" ); sepOff( os ); f.val = -f.val; f.flags.sign = false; } \
    640                         } /* if */ \
    641                         base10_128( os, f ); \
    642                 } /* if */ \
    643                 return os; \
    644         } /* ?|? */ \
    645         void ?|?( ostype & os, _Ostream_Manip(T) f ) { (ostype &)(os | f); ends( os ); } \
    646 } // distribution
    647 
    648 IntegralFMTImpl128( int128, signed, 'd', "%    *ll ", "%    *.*ll " )
    649 IntegralFMTImpl128( unsigned int128, unsigned, 'u', "%    *ll ", "%    *.*ll " )
    650 #endif // __SIZEOF_INT128__
    651 #endif // 0
    652 
    653 #if 1
    654 #if defined( __SIZEOF_INT128__ )
    655 // Default prefix for non-decimal prints is 0b, 0, 0x.
    656 forall( dtype ostype | ostream( ostype ) )
    657 static 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 ) {
    658         int wd = 1;                                                                                     // f.wd is never 0 because 0 implies left-pad
    659         if ( val > power ) {                                                            // subdivide value into printable 64-bit values
    660                 base_128( os, val / power, power, f, maxdig, bits, cnt + 1 ); // recursive
    661                 f.val = val % power;
    662                 if ( cnt == 1 && f.flags.left ) { wd = f.wd; f.wd = maxdig; } // copy f.wd and reset for printing middle chunk
    663                 // printf( "R val:%#lx(%lu) wd:%u pc:%u base:%c neg:%d pc:%d left:%d nobsdp:%d sign:%d pad0:%d\n",
    664                 //              f.val, f.val, f.wd, f.pc, f.base, f.flags.neg, f.flags.pc, f.flags.left, f.flags.nobsdp, f.flags.sign, f.flags.pad0 );
    665                 (ostype &)(os | f);
    666                 if ( cnt == 1 ) {
    667                         if ( f.flags.left ) { wd -= maxdig; f.wd = wd < 0 ? 1 : wd; } // update and restore f.wd for printing end chunk
    668                         sepOff( os );                                                           // no seperator between chunks
    669                 } // if
    670         } else {                                                                                        // print start chunk
    671                 f.val = val;
    672                 // f.pc is unsigned => use wd
    673                 if ( f.flags.pc && f.pc > maxdig * cnt ) { wd = f.pc - maxdig * cnt; f.pc = wd < 0 ? 0 : wd; }
    674                 else { f.flags.pc = false; f.pc = 0; }
    675 
    676                 if ( ! f.flags.left ) {                                                 // right justify
    677                         wd = f.wd - maxdig * cnt;
    678                         f.wd = wd < 0 ? 1 : wd;
    679                         wd = maxdig;
    680                 } else {                                                                                // left justify
    681                         if ( cnt != 0 ) {                                                       // value >= 2^64 ?
    682                                 unsigned int dig, bs = 0;
    683                                 // compute size of prefix digits and base
    684                                 if ( f.base == 'd' || f.base == 'u' ) { // no base prefix
    685                                         dig = ceil( log10( f.val ) );           // use floating-point
    686                                         if ( f.base == 'd' && (f.flags.neg || f.flags.sign) ) bs = 1; // sign ?
    687                                 } else {
    688                                         dig = ceiling_div( high1( f.val ), bits );
    689                                         if ( ! f.flags.nobsdp ) {                       // base prefix ?
    690                                                 if ( f.base == 'o' ) {
    691                                                         // 0 prefix for octal is not added for precision with leading zero
    692                                                         if ( f.pc <= dig ) bs = 1;      // 1 character prefix
    693                                                 } else bs = 2;                                  // 2 character prefix
    694                                         } // if
    695                                 } // if
    696                                 wd = f.wd - (f.pc > dig ? f.pc : dig) - bs; // precision > leading digits ?
    697                                 if ( wd < 0 ) wd = 1;
    698                                 f.wd = 1;
    699                         } // if
    700                         // all manipulators handled implicitly for value < 2^64
    701                 } // if
    702                 // prior checks ensure wd not negative
    703 
    704                 if ( f.flags.neg ) f.val = -f.val;
    705                 // printf( "L val:%#lx(%lu) wd:%u pc:%u base:%c neg:%d pc:%d left:%d nobsdp:%d sign:%d pad0:%d\n",
    706                 //              f.val, f.val, f.wd, f.pc, f.base, f.flags.neg, f.flags.pc, f.flags.left, f.flags.nobsdp, f.flags.sign, f.flags.pad0 );
    707                 (ostype &)(os | f);
    708 
    709                 // remaining middle and end chunks are padded with 0s on the left
    710                 if ( ! f.flags.left ) { f.flags.pad0 = true; f.flags.pc = false; } // left pad with 0s
    711                 else { f.pc = maxdig; f.flags.pc = true; }              // left pad with precision
    712 
    713                 if ( cnt != 0 ) sepOff( os );                                   // no seperator between chunks
    714                 f.wd = wd;                                                                              // reset f.wd for next chunk
    715                 f.flags.sign = false;                                                   // no leading +/- sign
    716                 f.flags.nobsdp = true;                                                  // no leading base prefix
    717         } // if
    718 } // base_128
    719 
    720 #define IntegralFMTImpl128( T ) \
    721 forall( dtype ostype | ostream( ostype ) ) { \
    722         ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \
    723                 _Ostream_Manip(uint64_t) fmt; \
    724                 fmt.[wd, pc, base, all] = f.[wd, pc, base, all]; \
    725                 if ( f.base == 'b' | f.base == 'B' ) { \
    726                         base_128( os, f.val, (unsigned int128)1 << 64, fmt, 64, 1 ); \
    727                 } else if ( f.base == 'o' ) { \
    728                         base_128( os, f.val, (unsigned int128)1 << 63, fmt, 21, 3 ); \
    729                 } else if ( f.base == 'd' || f.base == 'u' ) { \
    730                         if ( f.base == 'd' && f.val < 0 ) { f.val = -f.val; fmt.flags.neg = true; } \
    731                         base_128( os, f.val, (unsigned int128)10_000_000_000_000_000_000UL, fmt, 19, 0 ); \
    732                 } else { \
    733                         base_128( os, f.val, (unsigned int128)1 << 64, fmt, 16, 4 ); \
    734                 } /* if */ \
    735                 return os; \
    736         } /* ?|? */ \
    737         void ?|?( ostype & os, _Ostream_Manip(T) f ) { (ostype &)(os | f); ends( os ); } \
    738 } // distribution
    739 
    740 IntegralFMTImpl128( int128 )
    741 IntegralFMTImpl128( unsigned int128 )
    742 #endif // __SIZEOF_INT128__
    743 #endif // 0
    744 
    745 // *********************************** floating point ***********************************
     478IntegralFMTImpl( signed char, 'd', "%    *hh ", "%    *.*hh " )
     479IntegralFMTImpl( unsigned char, 'u', "%    *hh ", "%    *.*hh " )
     480IntegralFMTImpl( signed short int, 'd', "%    *h ", "%    *.*h " )
     481IntegralFMTImpl( unsigned short int, 'u', "%    *h ", "%    *.*h " )
     482IntegralFMTImpl( signed int, 'd', "%    * ", "%    *.* " )
     483IntegralFMTImpl( unsigned int, 'u', "%    * ", "%    *.* " )
     484IntegralFMTImpl( signed long int, 'd', "%    *l ", "%    *.*l " )
     485IntegralFMTImpl( unsigned long int, 'u', "%    *l ", "%    *.*l " )
     486IntegralFMTImpl( signed long long int, 'd', "%    *ll ", "%    *.*ll " )
     487IntegralFMTImpl( unsigned long long int, 'u', "%    *ll ", "%    *.*ll " )
     488
     489//*********************************** floating point ***********************************
    746490
    747491#define PrintWithDP2( os, format, val, ... ) \
     
    769513forall( dtype ostype | ostream( ostype ) ) { \
    770514        ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \
    771                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) ); \
     515                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) ); \
    772516                char fmtstr[sizeof(DFMTP)];                                             /* sizeof includes '\0' */ \
    773517                if ( ! f.flags.pc ) memcpy( &fmtstr, DFMTNP, sizeof(DFMTNP) ); \
     
    792536                return os; \
    793537        } /* ?|? */ \
    794 \
    795538        void ?|?( ostype & os, _Ostream_Manip(T) f ) { (ostype &)(os | f); ends( os ); } \
    796539} // distribution
     
    799542FloatingPointFMTImpl( long double, "%    *L ", "%    *.*L " )
    800543
    801 // *********************************** character ***********************************
     544//*********************************** character ***********************************
    802545
    803546forall( dtype ostype | ostream( ostype ) ) {
     
    812555                } // if
    813556
    814                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     557                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    815558
    816559                #define CFMTNP "% * "
     
    828571                return os;
    829572        } // ?|?
    830 
    831573        void ?|?( ostype & os, _Ostream_Manip(char) f ) { (ostype &)(os | f); ends( os ); }
    832574} // distribution
    833575
    834 // *********************************** C string ***********************************
     576//*********************************** C string ***********************************
    835577
    836578forall( dtype ostype | ostream( ostype ) ) {
     
    850592                } // if
    851593
    852                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     594                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    853595
    854596                #define SFMTNP "% * "
     
    874616                return os;
    875617        } // ?|?
    876 
    877618        void ?|?( ostype & os, _Ostream_Manip(const char *) f ) { (ostype &)(os | f); ends( os ); }
    878619} // distribution
    879620
    880621
    881 // *********************************** istream ***********************************
     622//*********************************** istream ***********************************
    882623
    883624
     
    956697        } // ?|?
    957698
    958 #if defined( __SIZEOF_INT128__ )
    959         istype & ?|?( istype & is, int128 & i128 ) {
    960                 return (istype &)(is | (unsigned int128 &)i128);
    961         } // ?|?
    962 
    963         istype & ?|?( istype & is, unsigned int128 & ui128 ) {
    964                 char s[40];
    965                 bool sign = false;
    966 
    967                 if ( fmt( is, " %[-]", s ) == 1 ) sign = true;  // skip whitespace, negative sign ?
    968                 // If the input is too large, the value returned is undefined. If there is no input, no value is returned
    969                 if ( fmt( is, "%39[0-9]%*[0-9]", s ) == 1 ) {   // take first 39 characters, ignore remaining
    970                         ui128 = 0;
    971                         for ( unsigned int i = 0; s[i] != '\0'; i += 1 ) {
    972                                 ui128 = ui128 * 10 + s[i] - '0';
    973                         } // for
    974                         if ( sign ) ui128 = -ui128;
    975                 } else if ( sign ) ungetc( is, '-' );                   // return minus when no digits
    976                 return is;
    977         } // ?|?
    978 #endif // __SIZEOF_INT128__
    979699
    980700        istype & ?|?( istype & is, float & f ) {
     
    1015735        } // ?|?
    1016736
    1017         // istype & ?|?( istype & is, const char fmt[] ) {
     737        // istype & ?|?( istype & is, const char * fmt ) {
    1018738        //      fmt( is, fmt, "" );
    1019739        //      return is;
     
    1046766} // distribution
    1047767
    1048 // *********************************** manipulators ***********************************
     768//*********************************** manipulators ***********************************
    1049769
    1050770forall( dtype istype | istream( istype ) )
Note: See TracChangeset for help on using the changeset viewer.