Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/iostream.cfa

    r1adab3e ref3ac46  
    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 : Tue Apr 27 18:01:03 2021
     13// Update Count     : 1330
    1414//
    1515
     
    3636
    3737
    38 forall( ostype & | ostream( ostype ) ) {
     38forall( ostype & | basic_ostream( ostype ) ) {
    3939        ostype & ?|?( ostype & os, bool b ) {
    40                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     40                if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
    4141                fmt( os, "%s", b ? "true" : "false" );
    4242                return os;
     
    4848        ostype & ?|?( ostype & os, char c ) {
    4949                fmt( os, "%c", c );
    50                 if ( c == '\n' ) $setNL( os, true );
     50                if ( c == '\n' ) setNL$( os, true );
    5151                return sepOff( os );
    5252        } // ?|?
     
    5656
    5757        ostype & ?|?( ostype & os, signed char sc ) {
    58                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     58                if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
    5959                fmt( os, "%hhd", sc );
    6060                return os;
     
    6565
    6666        ostype & ?|?( ostype & os, unsigned char usc ) {
    67                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     67                if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
    6868                fmt( os, "%hhu", usc );
    6969                return os;
     
    7474
    7575        ostype & ?|?( ostype & os, short int si ) {
    76                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     76                if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
    7777                fmt( os, "%hd", si );
    7878                return os;
     
    8383
    8484        ostype & ?|?( ostype & os, unsigned short int usi ) {
    85                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     85                if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
    8686                fmt( os, "%hu", usi );
    8787                return os;
     
    9292
    9393        ostype & ?|?( ostype & os, int i ) {
    94                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     94                if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
    9595                fmt( os, "%d", i );
    9696                return os;
     
    101101
    102102        ostype & ?|?( ostype & os, unsigned int ui ) {
    103                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     103                if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
    104104                fmt( os, "%u", ui );
    105105                return os;
     
    110110
    111111        ostype & ?|?( ostype & os, long int li ) {
    112                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     112                if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
    113113                fmt( os, "%ld", li );
    114114                return os;
     
    119119
    120120        ostype & ?|?( ostype & os, unsigned long int uli ) {
    121                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     121                if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
    122122                fmt( os, "%lu", uli );
    123123                return os;
     
    128128
    129129        ostype & ?|?( ostype & os, long long int lli ) {
    130                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     130                if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
    131131                fmt( os, "%lld", lli );
    132132                return os;
     
    137137
    138138        ostype & ?|?( ostype & os, unsigned long long int ulli ) {
    139                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     139                if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
    140140                fmt( os, "%llu", ulli );
    141141                return os;
     
    145145        } // ?|?
    146146
    147 #if defined( __SIZEOF_INT128__ )
     147        #if defined( __SIZEOF_INT128__ )
    148148        //      UINT64_MAX 18_446_744_073_709_551_615_ULL
    149149        #define P10_UINT64 10_000_000_000_000_000_000_ULL       // 19 zeroes
    150150
    151151        static inline void base10_128( ostype & os, unsigned int128 val ) {
    152 #if defined(__GNUC__) && __GNUC_PREREQ(7,0)                             // gcc version >= 7
     152                #if defined(__GNUC__) && __GNUC_PREREQ(7,0)             // gcc version >= 7
    153153                if ( val > P10_UINT64 ) {
    154 #else
     154                #else
    155155                if ( (uint64_t)(val >> 64) != 0 || (uint64_t)val > P10_UINT64 ) { // patch gcc 5 & 6 -O3 bug
    156 #endif // __GNUC_PREREQ(7,0)
     156                #endif // __GNUC_PREREQ(7,0)
    157157                        base10_128( os, val / P10_UINT64 );                     // recursive
    158158                        fmt( os, "%.19lu", (uint64_t)(val % P10_UINT64) );
     
    171171
    172172        ostype & ?|?( ostype & os, int128 llli ) {
    173                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     173                if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
    174174                base10_128( os, llli );
    175175                return os;
     
    180180
    181181        ostype & ?|?( ostype & os, unsigned int128 ullli ) {
    182                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     182                if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
    183183                base10_128( os, ullli );
    184184                return os;
     
    187187                (ostype &)(os | ullli); ends( os );
    188188        } // ?|?
    189 #endif // __SIZEOF_INT128__
     189        #endif // __SIZEOF_INT128__
    190190
    191191        #define PrintWithDP( os, format, val, ... ) \
     
    195195                        int len = snprintf( buf, size, format, ##__VA_ARGS__, val ); \
    196196                        fmt( os, "%s", buf ); \
    197                         if ( isfinite( val ) ) {                                        /* if number, always print decimal point */ \
     197                        if ( isfinite( val ) ) { /* if number, print decimal point when no fraction or exponent */ \
    198198                                for ( int i = 0;; i += 1 ) { \
    199199                                        if ( i == len ) { fmt( os, "." ); break; } \
    200                                         if ( buf[i] == '.' ) break; \
     200                                        if ( buf[i] == '.' || buf[i] == 'e' || buf[i] == 'E' ) break; /* decimal point or scientific ? */ \
    201201                                } /* for */ \
    202202                        } /* if */ \
     
    204204
    205205        ostype & ?|?( ostype & os, float f ) {
    206                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     206                if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
    207207                PrintWithDP( os, "%g", f );
    208208                return os;
     
    213213
    214214        ostype & ?|?( ostype & os, double d ) {
    215                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     215                if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
    216216                PrintWithDP( os, "%.*lg", d, DBL_DIG );
    217217                return os;
     
    222222
    223223        ostype & ?|?( ostype & os, long double ld ) {
    224                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     224                if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
    225225                PrintWithDP( os, "%.*Lg", ld, LDBL_DIG );
    226226                return os;
     
    231231
    232232        ostype & ?|?( ostype & os, float _Complex fc ) {
    233                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     233                if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
    234234//              os | crealf( fc ) | nonl;
    235235                PrintWithDP( os, "%g", crealf( fc ) );
     
    243243
    244244        ostype & ?|?( ostype & os, double _Complex dc ) {
    245                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     245                if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
    246246//              os | creal( dc ) | nonl;
    247247                PrintWithDP( os, "%.*lg", creal( dc ), DBL_DIG );
     
    255255
    256256        ostype & ?|?( ostype & os, long double _Complex ldc ) {
    257                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     257                if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
    258258//              os | creall( ldc ) || nonl;
    259259                PrintWithDP( os, "%.*Lg", creall( ldc ), LDBL_DIG );
     
    266266        } // ?|?
    267267
    268         ostype & ?|?( ostype & os, const char str[] ) {
     268        ostype & ?|?( ostype & os, const char s[] ) {
    269269                enum { Open = 1, Close, OpenClose };
    270270                static const unsigned char mask[256] @= {
     
    282282                }; // mask
    283283
    284           if ( str[0] == '\0' ) { sepOff( os ); return os; } // null string => no separator
     284          if ( s[0] == '\0' ) { sepOff( os ); return os; } // null string => no separator
    285285
    286286                // first character IS NOT spacing or closing punctuation => add left separator
    287                 unsigned char ch = str[0];                                              // must make unsigned
    288                 if ( $sepPrt( os ) && mask[ ch ] != Close && mask[ ch ] != OpenClose ) {
    289                         fmt( os, "%s", $sepGetCur( os ) );
     287                unsigned char ch = s[0];                                                // must make unsigned
     288                if ( sepPrt$( os ) && mask[ ch ] != Close && mask[ ch ] != OpenClose ) {
     289                        fmt( os, "%s", sepGetCur$( os ) );
    290290                } // if
    291291
    292292                // if string starts line, must reset to determine open state because separator is off
    293                 $sepReset( os );                                                                // reset separator
     293                sepReset$( os );                                                                // reset separator
    294294
    295295                // last character IS spacing or opening punctuation => turn off separator for next item
    296                 size_t len = strlen( str );
    297                 ch = str[len - 1];                                                              // must make unsigned
    298                 if ( $sepPrt( os ) && mask[ ch ] != Open && mask[ ch ] != OpenClose ) {
     296                int len = strlen( s );
     297                ch = s[len - 1];                                                                // must make unsigned
     298                fmt( os, "%s", s );                                                             // fmt resets seperator, but reset it again
     299                if ( sepPrt$( os ) && mask[ ch ] != Open && mask[ ch ] != OpenClose ) {
    299300                        sepOn( os );
    300301                } else {
    301302                        sepOff( os );
    302303                } // if
    303                 if ( ch == '\n' ) $setNL( os, true );                   // check *AFTER* $sepPrt call above as it resets NL flag
    304                 return write( os, str, len );
    305         } // ?|?
    306 
    307         void ?|?( ostype & os, const char str[] ) {
    308                 (ostype &)(os | str); ends( os );
    309         } // ?|?
    310 
    311 //      ostype & ?|?( ostype & os, const char16_t * str ) {
    312 //              if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    313 //              fmt( os, "%ls", str );
     304                if ( ch == '\n' ) setNL$( os, true );                   // check *AFTER* sepPrt$ call above as it resets NL flag
     305                return os;
     306//              return write( os, s, len );
     307        } // ?|?
     308        void ?|?( ostype & os, const char s[] ) {
     309                (ostype &)(os | s); ends( os );
     310        } // ?|?
     311
     312//      ostype & ?|?( ostype & os, const char16_t * s ) {
     313//              if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
     314//              fmt( os, "%ls", s );
    314315//              return os;
    315316//      } // ?|?
    316317
    317318// #if ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 ) // char32_t == wchar_t => ambiguous
    318 //      ostype & ?|?( ostype & os, const char32_t * str ) {
    319 //              if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    320 //              fmt( os, "%ls", str );
     319//      ostype & ?|?( ostype & os, const char32_t * s ) {
     320//              if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
     321//              fmt( os, "%ls", s );
    321322//              return os;
    322323//      } // ?|?
    323324// #endif // ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 )
    324325
    325 //      ostype & ?|?( ostype & os, const wchar_t * str ) {
    326 //              if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    327 //              fmt( os, "%ls", str );
     326//      ostype & ?|?( ostype & os, const wchar_t * s ) {
     327//              if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
     328//              fmt( os, "%ls", s );
    328329//              return os;
    329330//      } // ?|?
    330331
    331332        ostype & ?|?( ostype & os, const void * p ) {
    332                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     333                if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
    333334                fmt( os, "%p", p );
    334335                return os;
     
    340341        // manipulators
    341342        ostype & ?|?( ostype & os, ostype & (* manip)( ostype & ) ) {
    342                 (ostype &)(manip( os ));
    343                 return os;
     343                return manip( os );
    344344        } // ?|?
    345345        void ?|?( ostype & os, ostype & (* manip)( ostype & ) ) {
    346                 (ostype &)(manip( os ));
    347                 if ( $getPrt( os ) ) ends( os );                                // something printed ?
    348                 $setPrt( os, false );                                                   // turn off
     346                manip( os );
     347                if ( getPrt$( os ) ) ends( os );                                // something printed ?
     348                setPrt$( os, false );                                                   // turn off
    349349        } // ?|?
    350350
     
    359359        ostype & nl( ostype & os ) {
    360360                (ostype &)(os | '\n');
    361                 $setPrt( os, false );                                                   // turn off
    362                 $setNL( os, true );
    363                 flush( os );
     361                setPrt$( os, false );                                                   // turn off
     362                setNL$( os, true );
    364363                return sepOff( os );                                                    // prepare for next line
    365364        } // nl
    366365
    367366        ostype & nonl( ostype & os ) {
    368                 $setPrt( os, false );                                                   // turn off
     367                setPrt$( os, false );                                                   // turn off
    369368                return os;
    370369        } // nonl
     
    399398                return os;
    400399        } // nlOff
     400} // distribution
     401
     402forall( ostype & | ostream( ostype ) ) {
     403        ostype & acquire( ostype & os ) {
     404                acquire( os );                                                                  // call void returning
     405                return os;
     406        } // acquire
    401407} // distribution
    402408
     
    405411        ostype & ?|?( ostype & os, T arg, Params rest ) {
    406412                (ostype &)(os | arg);                                                   // print first argument
    407                 $sepSetCur( os, sepGetTuple( os ) );                    // switch to tuple separator
     413                sepSetCur$( os, sepGetTuple( os ) );                    // switch to tuple separator
    408414                (ostype &)(os | rest);                                                  // print remaining arguments
    409                 $sepSetCur( os, sepGet( os ) );                                 // switch to regular separator
     415                sepSetCur$( os, sepGet( os ) );                                 // switch to regular separator
    410416                return os;
    411417        } // ?|?
     
    413419                // (ostype &)(?|?( os, arg, rest )); ends( os );
    414420                (ostype &)(os | arg);                                                   // print first argument
    415                 $sepSetCur( os, sepGetTuple( os ) );                    // switch to tuple separator
     421                sepSetCur$( os, sepGetTuple( os ) );                    // switch to tuple separator
    416422                (ostype &)(os | rest);                                                  // print remaining arguments
    417                 $sepSetCur( os, sepGet( os ) );                                 // switch to regular separator
     423                sepSetCur$( os, sepGet( os ) );                                 // switch to regular separator
    418424                ends( os );
    419425        } // ?|?
     
    442448// Default prefix for non-decimal prints is 0b, 0, 0x.
    443449#define IntegralFMTImpl( T, IFMTNP, IFMTP ) \
    444 forall( ostype & | ostream( ostype ) ) { \
     450forall( ostype & | basic_ostream( ostype ) ) { \
    445451        ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \
    446                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) ); \
     452                if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) ); \
    447453\
    448454                if ( f.base == 'b' || f.base == 'B' ) {                 /* bespoke binary format */ \
     
    517523                return os; \
    518524        } /* ?|? */ \
    519         void ?|?( ostype & os, _Ostream_Manip(T) f ) { (ostype &)(os | f); ends( os ); } \
    520 } // distribution
    521 
    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
     525        void ?|?( ostype & os, _Ostream_Manip(T) f ) { \
     526                (ostype &)(os | f); ends( os ); \
     527        } /* ?|? */ \
     528} // distribution
     529
     530IntegralFMTImpl( signed char, "     *hh ", "     *.*hh " )
     531IntegralFMTImpl( unsigned char, "     *hh ", "     *.*hh " )
     532IntegralFMTImpl( signed short int, "     *h ", "     *.*h " )
     533IntegralFMTImpl( unsigned short int, "     *h ", "     *.*h " )
     534IntegralFMTImpl( signed int, "     * ", "     *.* " )
     535IntegralFMTImpl( unsigned int, "     * ", "     *.* " )
     536IntegralFMTImpl( signed long int, "     *l ", "     *.*l " )
     537IntegralFMTImpl( unsigned long int, "     *l ", "     *.*l " )
     538IntegralFMTImpl( signed long long int, "     *ll ", "     *.*ll " )
     539IntegralFMTImpl( unsigned long long int, "     *ll ", "     *.*ll " )
     540
     541
    534542#if defined( __SIZEOF_INT128__ )
    535543// Default prefix for non-decimal prints is 0b, 0, 0x.
    536 #define IntegralFMTImpl128( T, SIGNED, CODE, IFMTNP, IFMTP ) \
    537 forall( 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( 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( ostype & | ostream( ostype ) )
     544forall( ostype & | basic_ostream( ostype ) )
    657545static 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 ) {
    658546        int wd = 1;                                                                                     // f.wd is never 0 because 0 implies left-pad
     
    719607
    720608#define IntegralFMTImpl128( T ) \
    721 forall( ostype & | ostream( ostype ) ) { \
     609forall( ostype & | basic_ostream( ostype ) ) { \
    722610        ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \
    723611                _Ostream_Manip(uint64_t) fmt; \
     
    741629IntegralFMTImpl128( unsigned int128 )
    742630#endif // __SIZEOF_INT128__
    743 #endif // 0
    744631
    745632// *********************************** floating point ***********************************
    746633
    747 #define PrintWithDP2( os, format, val, ... ) \
     634static const char *suffixes[] = {
     635        "y", "z", "a", "f", "p", "n", "u", "m", "",
     636        "K", "M", "G", "T", "P", "E", "Z", "Y"
     637};
     638#define SUFFIXES_START (-24) /* Smallest power for which there is a suffix defined. */
     639#define SUFFIXES_END (SUFFIXES_START + (int)((sizeof(suffixes) / sizeof(char *) - 1) * 3))
     640
     641#define PrintWithDP2( os, format, ... ) \
    748642        { \
    749                 enum { size = 48 }; \
    750                 char buf[size]; \
    751                 int bufbeg = 0, i, len = snprintf( buf, size, format, ##__VA_ARGS__, val ); \
    752                 if ( isfinite( val ) && (f.base != 'g' || f.pc != 0) ) { /* if number, print decimal point */ \
    753                         for ( i = 0; i < len && buf[i] != '.' && buf[i] != 'e' && buf[i] != 'E'; i += 1 ); /* decimal point or scientific ? */ \
    754                         if ( i == len && ! f.flags.nobsdp ) { \
    755                                 if ( ! f.flags.left ) { \
    756                                         buf[i] = '.'; buf[i + 1] = '\0'; \
    757                                         if ( buf[0] == ' ' ) bufbeg = 1;        /* decimal point within width */ \
    758                                 } else { \
    759                                         for ( i = 0; i < len && buf[i] != ' '; i += 1 ); /* trailing blank ? */ \
    760                                         buf[i] = '.'; \
    761                                         if ( i == len ) buf[i + 1] = '\0'; \
     643                if ( ! f.flags.eng ) { \
     644                        len = snprintf( buf, size, format, ##__VA_ARGS__ ); \
     645                        if ( isfinite( f.val ) && ( f.pc != 0 || ! f.flags.nobsdp ) ) { /* if number, print decimal point when no fraction or exponent */ \
     646                                for ( i = 0; i < len && buf[i] != '.' && buf[i] != 'e' && buf[i] != 'E'; i += 1 ); /* decimal point or scientific ? */ \
     647                                if ( i == len ) { \
     648                                        if ( ! f.flags.left ) { \
     649                                                buf[i] = '.'; buf[i + 1] = '\0'; \
     650                                                if ( buf[0] == ' ' ) bufbeg = 1; /* decimal point within width */ \
     651                                        } else { \
     652                                                for ( i = 0; i < len && buf[i] != ' '; i += 1 ); /* trailing blank ? */ \
     653                                                buf[i] = '.'; \
     654                                                if ( i == len ) buf[i + 1] = '\0'; \
     655                                        } /* if */ \
    762656                                } /* if */ \
    763657                        } /* if */ \
     658                } else { \
     659                        int exp10, len2; \
     660                        eng( f.val, f.pc, exp10 );                                      /* changes arguments */ \
     661                        if ( ! f.flags.left && f.wd > 1 ) { \
     662                                /* Exponent size (number of digits, 'e', optional minus sign) */ \
     663                                f.wd -= lrint( floor( log10( abs( exp10 ) ) ) ) + 1 + 1 + (exp10 < 0 ? 1 : 0); \
     664                                if ( f.wd < 1 ) f.wd = 1; \
     665                        } /* if */ \
     666                        len = snprintf( buf, size, format, ##__VA_ARGS__ ); \
     667                        if ( f.flags.left ) { \
     668                                for ( len -= 1; len > 0 && buf[len] == ' '; len -= 1 ); \
     669                                len += 1; \
     670                        } /* if */ \
     671                        if ( ! f.flags.nobsdp || (exp10 < SUFFIXES_START) || (exp10 > SUFFIXES_END) ) { \
     672                                len2 = snprintf( &buf[len], size - len, "e%d", exp10 ); \
     673                        } else { \
     674                                len2 = snprintf( &buf[len], size - len, "%s", suffixes[(exp10 - SUFFIXES_START) / 3] ); \
     675                        } /* if */ \
     676                        if ( f.flags.left && len + len2 < f.wd ) buf[len + len2] = ' '; \
    764677                } /* if */ \
    765678                fmt( os, "%s", &buf[bufbeg] ); \
     
    767680
    768681#define FloatingPointFMTImpl( T, DFMTNP, DFMTP ) \
    769 forall( ostype & | ostream( ostype ) ) { \
     682forall( ostype & | basic_ostream( ostype ) ) { \
     683        static void eng( T &value, int & pc, int & exp10 ) { \
     684                exp10 = lrint( floor( log10( abs( value ) ) ) ); /* round to desired precision */ \
     685                if ( exp10 < 0 ) exp10 -= 2; \
     686                exp10 = floor( exp10, 3 ); \
     687                value *= pow( 10.0, -exp10 ); \
     688                if ( pc <= 3 ) pc = 3; \
     689        } /* eng */ \
     690\
    770691        ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \
    771                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) ); \
    772                 char fmtstr[sizeof(DFMTP)];                                             /* sizeof includes '\0' */ \
     692                enum { size = 48 }; \
     693                char buf[size]; \
     694                int bufbeg = 0, i, len; \
     695\
     696                if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) ); \
     697                char fmtstr[sizeof(DFMTP) + 8];                                 /* sizeof includes '\0' */ \
    773698                if ( ! f.flags.pc ) memcpy( &fmtstr, DFMTNP, sizeof(DFMTNP) ); \
    774699                else memcpy( &fmtstr, DFMTP, sizeof(DFMTP) ); \
     
    784709                        fmtstr[sizeof(DFMTNP)-2] = f.base;                      /* sizeof includes '\0' */ \
    785710                        /* printf( "%g %d %s\n", f.val, f.wd, &fmtstr[star]); */ \
    786                         PrintWithDP2( os, &fmtstr[star], f.val, f.wd ) \
     711                        PrintWithDP2( os, &fmtstr[star], f.wd, f.val ) \
    787712                } else {                                                                                /* precision */ \
    788713                        fmtstr[sizeof(DFMTP)-2] = f.base;                       /* sizeof includes '\0' */ \
    789714                        /* printf( "%g %d %d %s\n", f.val, f.wd, f.pc, &fmtstr[star] ); */ \
    790                         PrintWithDP2( os, &fmtstr[star], f.val, f.wd, f.pc ) \
     715                        PrintWithDP2( os, &fmtstr[star], f.wd, f.pc, f.val ) \
    791716                } /* if */ \
    792717                return os; \
     
    796721} // distribution
    797722
    798 FloatingPointFMTImpl( double, "%    * ", "%    *.* " )
    799 FloatingPointFMTImpl( long double, "%    *L ", "%    *.*L " )
     723FloatingPointFMTImpl( double, "     * ", "     *.* " )
     724FloatingPointFMTImpl( long double, "     *L ", "     *.*L " )
    800725
    801726// *********************************** character ***********************************
    802727
    803 forall( ostype & | ostream( ostype ) ) {
     728forall( ostype & | basic_ostream( ostype ) ) {
    804729        ostype & ?|?( ostype & os, _Ostream_Manip(char) f ) {
    805730                if ( f.base != 'c' ) {                                                  // bespoke binary/octal/hex format
     
    812737                } // if
    813738
    814                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     739                if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
    815740
    816741                #define CFMTNP "% * "
     
    834759// *********************************** C string ***********************************
    835760
    836 forall( ostype & | ostream( ostype ) ) {
     761forall( ostype & | basic_ostream( ostype ) ) {
    837762        ostype & ?|?( ostype & os, _Ostream_Manip(const char *) f ) {
    838763                if ( ! f.val ) return os;                                               // null pointer ?
     
    850775                } // if
    851776
    852                 if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     777                if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
    853778
    854779                #define SFMTNP "% * "
     
    882807
    883808
    884 forall( istype & | istream( istype ) ) {
     809forall( istype & | basic_istream( istype ) ) {
    885810        istype & ?|?( istype & is, bool & b ) {
    886811                char val[6];
     
    894819                return is;
    895820        } // ?|?
     821        void ?|?( istype & is, bool & b ) {
     822                (istype &)(is | b); ends( is );
     823        } // ?|?
    896824
    897825        istype & ?|?( istype & is, char & c ) {
     
    905833                return is;
    906834        } // ?|?
     835        void ?|?( istype & is, char & c ) {
     836                (istype &)(is | c); ends( is );
     837        } // ?|?
    907838
    908839        istype & ?|?( istype & is, signed char & sc ) {
     
    910841                return is;
    911842        } // ?|?
     843        void ?|?( istype & is, signed char & sc ) {
     844                (istype &)(is | sc); ends( is );
     845        } // ?|?
    912846
    913847        istype & ?|?( istype & is, unsigned char & usc ) {
     
    915849                return is;
    916850        } // ?|?
     851        void ?|?( istype & is, unsigned char & usc ) {
     852                (istype &)(is | usc); ends( is );
     853        } // ?|?
    917854
    918855        istype & ?|?( istype & is, short int & si ) {
     
    920857                return is;
    921858        } // ?|?
     859        void ?|?( istype & is, short int & si ) {
     860                (istype &)(is | si); ends( is );
     861        } // ?|?
    922862
    923863        istype & ?|?( istype & is, unsigned short int & usi ) {
     
    925865                return is;
    926866        } // ?|?
     867        void ?|?( istype & is, unsigned short int & usi ) {
     868                (istype &)(is | usi); ends( is );
     869        } // ?|?
    927870
    928871        istype & ?|?( istype & is, int & i ) {
     
    930873                return is;
    931874        } // ?|?
     875        void ?|?( istype & is, int & i ) {
     876                (istype &)(is | i); ends( is );
     877        } // ?|?
    932878
    933879        istype & ?|?( istype & is, unsigned int & ui ) {
     
    935881                return is;
    936882        } // ?|?
     883        void ?|?( istype & is, unsigned int & ui ) {
     884                (istype &)(is | ui); ends( is );
     885        } // ?|?
    937886
    938887        istype & ?|?( istype & is, long int & li ) {
     
    940889                return is;
    941890        } // ?|?
     891        void ?|?( istype & is, long int & li ) {
     892                (istype &)(is | li); ends( is );
     893        } // ?|?
    942894
    943895        istype & ?|?( istype & is, unsigned long int & ulli ) {
     
    945897                return is;
    946898        } // ?|?
     899        void ?|?( istype & is, unsigned long int & ulli ) {
     900                (istype &)(is | ulli); ends( is );
     901        } // ?|?
    947902
    948903        istype & ?|?( istype & is, long long int & lli ) {
     
    950905                return is;
    951906        } // ?|?
     907        void ?|?( istype & is, long long int & lli ) {
     908                (istype &)(is | lli); ends( is );
     909        } // ?|?
    952910
    953911        istype & ?|?( istype & is, unsigned long long int & ulli ) {
     
    955913                return is;
    956914        } // ?|?
    957 
    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 ) {
     915        void & ?|?( istype & is, unsigned long long int & ulli ) {
     916                (istype &)(is | ulli); ends( is );
     917        } // ?|?
     918
     919        #if defined( __SIZEOF_INT128__ )
     920        istype & ?|?( istype & is, int128 & llli ) {
     921                return (istype &)(is | (unsigned int128 &)llli);
     922        } // ?|?
     923        void ?|?( istype & is, int128 & llli ) {
     924                (istype &)(is | llli); ends( is );
     925        } // ?|?
     926
     927        istype & ?|?( istype & is, unsigned int128 & ullli ) {
    964928                char s[40];
    965929                bool sign = false;
     
    968932                // If the input is too large, the value returned is undefined. If there is no input, no value is returned
    969933                if ( fmt( is, "%39[0-9]%*[0-9]", s ) == 1 ) {   // take first 39 characters, ignore remaining
    970                         ui128 = 0;
     934                        ullli = 0;
    971935                        for ( unsigned int i = 0; s[i] != '\0'; i += 1 ) {
    972                                 ui128 = ui128 * 10 + s[i] - '0';
     936                                ullli = ullli * 10 + s[i] - '0';
    973937                        } // for
    974                         if ( sign ) ui128 = -ui128;
     938                        if ( sign ) ullli = -ullli;
    975939                } else if ( sign ) ungetc( is, '-' );                   // return minus when no digits
    976940                return is;
    977941        } // ?|?
    978 #endif // __SIZEOF_INT128__
     942        void ?|?( istype & is, unsigned int128 & ullli ) {
     943                (istype &)(is | ullli); ends( is );
     944        } // ?|?
     945        #endif // __SIZEOF_INT128__
    979946
    980947        istype & ?|?( istype & is, float & f ) {
     
    982949                return is;
    983950        } // ?|?
     951        void ?|?( istype & is, float & f ) {
     952                (istype &)(is | f); ends( is );
     953        } // ?|?
    984954
    985955        istype & ?|?( istype & is, double & d ) {
     
    987957                return is;
    988958        } // ?|?
     959        void ?|?( istype & is, double & d ) {
     960                (istype &)(is | d); ends( is );
     961        } // ?|?
    989962
    990963        istype & ?|?( istype & is, long double & ld ) {
     
    992965                return is;
    993966        } // ?|?
    994 
     967        void ?|?( istype & is, long double & ld ) {
     968                (istype &)(is | ld); ends( is );
     969        } // ?|?
    995970
    996971        istype & ?|?( istype & is, float _Complex & fc ) {
     
    1000975                return is;
    1001976        } // ?|?
     977        void ?|?( istype & is, float _Complex & fc ) {
     978                (istype &)(is | fc); ends( is );
     979        } // ?|?
    1002980
    1003981        istype & ?|?( istype & is, double _Complex & dc ) {
     
    1007985                return is;
    1008986        } // ?|?
     987        void ?|?( istype & is, double _Complex & dc ) {
     988                (istype &)(is | dc); ends( is );
     989        } // ?|?
    1009990
    1010991        istype & ?|?( istype & is, long double _Complex & ldc ) {
     
    1014995                return is;
    1015996        } // ?|?
     997        void ?|?( istype & is, long double _Complex & ldc ) {
     998                (istype &)(is | ldc); ends( is );
     999        } // ?|?
    10161000
    10171001        // istype & ?|?( istype & is, const char fmt[] ) {
     
    10201004        // } // ?|?
    10211005
    1022         istype & ?|?( istype & is, char * s ) {
     1006        istype & ?|?( istype & is, char s[] ) {
    10231007                fmt( is, "%s", s );
    10241008                return is;
     1009        } // ?|?
     1010        void ?|?( istype & is, char s[] ) {
     1011                (istype &)(is | s); ends( is );
    10251012        } // ?|?
    10261013
     
    10291016                return manip( is );
    10301017        } // ?|?
     1018        void ?|?( istype & is, istype & (* manip)( istype & ) ) {
     1019                manip( is ); ends( is );
     1020        } // ?|?
    10311021
    10321022        istype & nl( istype & is ) {
     
    10461036} // distribution
    10471037
     1038forall( istype & | istream( istype ) ) {
     1039        istype & acquire( istype & is ) {
     1040                acquire( is );                                                                  // call void returning
     1041                return is;
     1042        } // acquire
     1043} // distribution
     1044
    10481045// *********************************** manipulators ***********************************
    10491046
    1050 forall( istype & | istream( istype ) )
    1051 istype & ?|?( istype & is, _Istream_Cstr f ) {
    1052         // skip xxx
    1053         if ( ! f.s ) {
    1054                 // printf( "skip %s %d\n", f.scanset, f.wd );
    1055                 if ( f.wd == -1 ) fmt( is, f.scanset, "" );             // no input arguments
    1056                 else for ( f.wd ) fmt( is, "%*c" );
    1057                 return is;
    1058         } // if
    1059         size_t len = 0;
    1060         if ( f.scanset ) len = strlen( f.scanset );
    1061         char fmtstr[len + 16];
    1062         int start = 1;
    1063         fmtstr[0] = '%';
    1064         if ( f.flags.ignore ) { fmtstr[1] = '*'; start += 1; }
    1065         if ( f.wd != -1 ) { start += sprintf( &fmtstr[start], "%d", f.wd ); }
    1066         // cstr %s, %*s, %ws, %*ws
    1067         if ( ! f.scanset ) {
    1068                 fmtstr[start] = 's'; fmtstr[start + 1] = '\0';
    1069                 // printf( "cstr %s\n", fmtstr );
     1047forall( istype & | basic_istream( istype ) ) {
     1048        istype & ?|?( istype & is, _Istream_Cstr f ) {
     1049                // skip xxx
     1050                if ( ! f.s ) {
     1051                        // printf( "skip %s %d\n", f.scanset, f.wd );
     1052                        if ( f.wd == -1 ) fmt( is, f.scanset, "" );             // no input arguments
     1053                        else for ( f.wd ) fmt( is, "%*c" );
     1054                        return is;
     1055                } // if
     1056                size_t len = 0;
     1057                if ( f.scanset ) len = strlen( f.scanset );
     1058                char fmtstr[len + 16];
     1059                int start = 1;
     1060                fmtstr[0] = '%';
     1061                if ( f.flags.ignore ) { fmtstr[1] = '*'; start += 1; }
     1062                if ( f.wd != -1 ) { start += sprintf( &fmtstr[start], "%d", f.wd ); }
     1063                // cstr %s, %*s, %ws, %*ws
     1064                if ( ! f.scanset ) {
     1065                        fmtstr[start] = 's'; fmtstr[start + 1] = '\0';
     1066                        // printf( "cstr %s\n", fmtstr );
     1067                        fmt( is, fmtstr, f.s );
     1068                        return is;
     1069                } // if
     1070                // incl %[xxx],  %*[xxx],  %w[xxx],  %*w[xxx]
     1071                // excl %[^xxx], %*[^xxx], %w[^xxx], %*w[^xxx]
     1072                fmtstr[start] = '['; start += 1;
     1073                if ( f.flags.inex ) { fmtstr[start] = '^'; start += 1; }
     1074                strcpy( &fmtstr[start], f.scanset );                            // copy includes '\0'
     1075                len += start;
     1076                fmtstr[len] = ']'; fmtstr[len + 1] = '\0';
     1077                // printf( "incl/excl %s\n", fmtstr );
    10701078                fmt( is, fmtstr, f.s );
    10711079                return is;
    1072         } // if
    1073         // incl %[xxx],  %*[xxx],  %w[xxx],  %*w[xxx]
    1074         // excl %[^xxx], %*[^xxx], %w[^xxx], %*w[^xxx]
    1075         fmtstr[start] = '['; start += 1;
    1076         if ( f.flags.inex ) { fmtstr[start] = '^'; start += 1; }
    1077         strcpy( &fmtstr[start], f.scanset );                            // copy includes '\0'
    1078         len += start;
    1079         fmtstr[len] = ']'; fmtstr[len + 1] = '\0';
    1080         // printf( "incl/excl %s\n", fmtstr );
    1081         fmt( is, fmtstr, f.s );
    1082         return is;
    1083 } // ?|?
    1084 
    1085 forall( istype & | istream( istype ) )
    1086 istype & ?|?( istype & is, _Istream_Char f ) {
    1087         fmt( is, "%*c" );                                                                       // argument variable unused
    1088         return is;
    1089 } // ?|?
     1080        } // ?|?
     1081        void ?|?( istype & is, _Istream_Cstr f ) {
     1082                (istype &)(is | f); ends( is );
     1083        } // ?|?
     1084
     1085        istype & ?|?( istype & is, _Istream_Char f ) {
     1086                fmt( is, "%*c" );                                                                       // argument variable unused
     1087                return is;
     1088        } // ?|?
     1089        void ?|?( istype & is, _Istream_Char f ) {
     1090                (istype &)(is | f); ends( is );
     1091        } // ?|?
     1092} // distribution
    10901093
    10911094#define InputFMTImpl( T, CODE ) \
    1092 forall( istype & | istream( istype ) ) \
    1093 istype & ?|?( istype & is, _Istream_Manip(T) f ) { \
    1094         enum { size = 16 }; \
    1095         char fmtstr[size]; \
    1096         if ( f.wd == -1 ) { \
    1097                 snprintf( fmtstr, size, "%%%s%s", f.ignore ? "*" : "", CODE ); \
    1098         } else { \
    1099                 snprintf( fmtstr, size, "%%%s%d%s", f.ignore ? "*" : "", f.wd, CODE ); \
    1100         } /* if */ \
    1101         /* printf( "%d %s %p\n", f.wd, fmtstr, &f.val ); */ \
    1102         fmt( is, fmtstr, &f.val ); \
    1103         return is; \
    1104 } // ?|?
     1095forall( istype & | basic_istream( istype ) ) { \
     1096        istype & ?|?( istype & is, _Istream_Manip(T) f ) { \
     1097                enum { size = 16 }; \
     1098                char fmtstr[size]; \
     1099                if ( f.wd == -1 ) { \
     1100                        snprintf( fmtstr, size, "%%%s%s", f.ignore ? "*" : "", CODE ); \
     1101                } else { \
     1102                        snprintf( fmtstr, size, "%%%s%d%s", f.ignore ? "*" : "", f.wd, CODE ); \
     1103                } /* if */ \
     1104                /* printf( "%d %s %p\n", f.wd, fmtstr, &f.val ); */ \
     1105                fmt( is, fmtstr, &f.val ); \
     1106                return is; \
     1107        } /* ?|? */ \
     1108        void ?|?( istype & is, _Istream_Manip(T) f ) { \
     1109                (istype &)(is | f); ends( is ); \
     1110        } /* ?|? */ \
     1111} // distribution
    11051112
    11061113InputFMTImpl( signed char, "hhi" )
     
    11191126InputFMTImpl( long double, "Lf" )
    11201127
    1121 forall( istype & | istream( istype ) )
    1122 istype & ?|?( istype & is, _Istream_Manip(float _Complex) fc ) {
    1123         float re, im;
    1124         _Istream_Manip(float) fmtuc @= { re, fc.wd, fc.ignore };
    1125         is | fmtuc;
    1126         &fmtuc.val = &im;
    1127         is | fmtuc;
    1128         if ( ! fc.ignore ) fc.val = re + im * _Complex_I;       // re/im are uninitialized for ignore
    1129         return is;
    1130 } // ?|?
    1131 
    1132 forall( istype & | istream( istype ) )
    1133 istype & ?|?( istype & is, _Istream_Manip(double _Complex) dc ) {
    1134         double re, im;
    1135         _Istream_Manip(double) fmtuc @= { re, dc.wd, dc.ignore };
    1136         is | fmtuc;
    1137         &fmtuc.val = &im;
    1138         is | fmtuc;
    1139         if ( ! dc.ignore ) dc.val = re + im * _Complex_I;       // re/im are uninitialized for ignore
    1140         return is;
    1141 } // ?|?
    1142 
    1143 forall( istype & | istream( istype ) )
    1144 istype & ?|?( istype & is, _Istream_Manip(long double _Complex) ldc ) {
    1145         long double re, im;
    1146         _Istream_Manip(long double) fmtuc @= { re, ldc.wd, ldc.ignore };
    1147         is | fmtuc;
    1148         &fmtuc.val = &im;
    1149         is | fmtuc;
    1150         if ( ! ldc.ignore ) ldc.val = re + im * _Complex_I;     // re/im are uninitialized for ignore
    1151         return is;
    1152 } // ?|?
     1128forall( istype & | basic_istream( istype ) ) {
     1129        istype & ?|?( istype & is, _Istream_Manip(float _Complex) fc ) {
     1130                float re, im;
     1131                _Istream_Manip(float) fmtuc @= { re, fc.wd, fc.ignore };
     1132                is | fmtuc;
     1133                &fmtuc.val = &im;
     1134                is | fmtuc;
     1135                if ( ! fc.ignore ) fc.val = re + im * _Complex_I; // re/im are uninitialized for ignore
     1136                return is;
     1137        } // ?|?
     1138        void ?|?( istype & is, _Istream_Manip(float _Complex) fc ) {
     1139                (istype &)(is | fc); ends( is );
     1140        } // ?|?
     1141
     1142        istype & ?|?( istype & is, _Istream_Manip(double _Complex) dc ) {
     1143                double re, im;
     1144                _Istream_Manip(double) fmtuc @= { re, dc.wd, dc.ignore };
     1145                is | fmtuc;
     1146                &fmtuc.val = &im;
     1147                is | fmtuc;
     1148                if ( ! dc.ignore ) dc.val = re + im * _Complex_I; // re/im are uninitialized for ignore
     1149                return is;
     1150        } // ?|?
     1151        void ?|?( istype & is, _Istream_Manip(double _Complex) dc ) {
     1152                (istype &)(is | dc); ends( is );
     1153        } // ?|?
     1154
     1155        istype & ?|?( istype & is, _Istream_Manip(long double _Complex) ldc ) {
     1156                long double re, im;
     1157                _Istream_Manip(long double) fmtuc @= { re, ldc.wd, ldc.ignore };
     1158                is | fmtuc;
     1159                &fmtuc.val = &im;
     1160                is | fmtuc;
     1161                if ( ! ldc.ignore ) ldc.val = re + im * _Complex_I;     // re/im are uninitialized for ignore
     1162                return is;
     1163        } // ?|?
     1164        void ?|?( istype & is, _Istream_Manip(long double _Complex) ldc ) {
     1165                (istype &)(is | ldc); ends( is );
     1166        } // ?|?
     1167} // distribution
    11531168
    11541169// Local Variables: //
Note: See TracChangeset for help on using the changeset viewer.