Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/iostream.cfa

    ref3ac46 r1adab3e  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Apr 27 18:01:03 2021
    13 // Update Count     : 1330
     12// Last Modified On : Mon Aug 24 08:31:35 2020
     13// Update Count     : 1130
    1414//
    1515
     
    3636
    3737
    38 forall( ostype & | basic_ostream( ostype ) ) {
     38forall( ostype & | 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, print decimal point when no fraction or exponent */ \
     197                        if ( isfinite( val ) ) {                                        /* if number, always print decimal point */ \
    198198                                for ( int i = 0;; i += 1 ) { \
    199199                                        if ( i == len ) { fmt( os, "." ); break; } \
    200                                         if ( buf[i] == '.' || buf[i] == 'e' || buf[i] == 'E' ) break; /* decimal point or scientific ? */ \
     200                                        if ( buf[i] == '.' ) break; \
    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 s[] ) {
     268        ostype & ?|?( ostype & os, const char str[] ) {
    269269                enum { Open = 1, Close, OpenClose };
    270270                static const unsigned char mask[256] @= {
     
    282282                }; // mask
    283283
    284           if ( s[0] == '\0' ) { sepOff( os ); return os; } // null string => no separator
     284          if ( str[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 = s[0];                                                // must make unsigned
    288                 if ( sepPrt$( os ) && mask[ ch ] != Close && mask[ ch ] != OpenClose ) {
    289                         fmt( os, "%s", sepGetCur$( os ) );
     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 ) );
    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                 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 ) {
     296                size_t len = strlen( str );
     297                ch = str[len - 1];                                                              // must make unsigned
     298                if ( $sepPrt( os ) && mask[ ch ] != Open && mask[ ch ] != OpenClose ) {
    300299                        sepOn( os );
    301300                } else {
    302301                        sepOff( os );
    303302                } // if
    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 );
     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 );
    315314//              return os;
    316315//      } // ?|?
    317316
    318317// #if ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 ) // char32_t == wchar_t => ambiguous
    319 //      ostype & ?|?( ostype & os, const char32_t * s ) {
    320 //              if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
    321 //              fmt( os, "%ls", s );
     318//      ostype & ?|?( ostype & os, const char32_t * str ) {
     319//              if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     320//              fmt( os, "%ls", str );
    322321//              return os;
    323322//      } // ?|?
    324323// #endif // ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 )
    325324
    326 //      ostype & ?|?( ostype & os, const wchar_t * s ) {
    327 //              if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
    328 //              fmt( os, "%ls", s );
     325//      ostype & ?|?( ostype & os, const wchar_t * str ) {
     326//              if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     327//              fmt( os, "%ls", str );
    329328//              return os;
    330329//      } // ?|?
    331330
    332331        ostype & ?|?( ostype & os, const void * p ) {
    333                 if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
     332                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    334333                fmt( os, "%p", p );
    335334                return os;
     
    341340        // manipulators
    342341        ostype & ?|?( ostype & os, ostype & (* manip)( ostype & ) ) {
    343                 return manip( os );
     342                (ostype &)(manip( os ));
     343                return os;
    344344        } // ?|?
    345345        void ?|?( ostype & os, ostype & (* manip)( ostype & ) ) {
    346                 manip( os );
    347                 if ( getPrt$( os ) ) ends( os );                                // something printed ?
    348                 setPrt$( os, false );                                                   // turn off
     346                (ostype &)(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 );
     361                $setPrt( os, false );                                                   // turn off
     362                $setNL( os, true );
     363                flush( os );
    363364                return sepOff( os );                                                    // prepare for next line
    364365        } // nl
    365366
    366367        ostype & nonl( ostype & os ) {
    367                 setPrt$( os, false );                                                   // turn off
     368                $setPrt( os, false );                                                   // turn off
    368369                return os;
    369370        } // nonl
     
    398399                return os;
    399400        } // nlOff
    400 } // distribution
    401 
    402 forall( ostype & | ostream( ostype ) ) {
    403         ostype & acquire( ostype & os ) {
    404                 acquire( os );                                                                  // call void returning
    405                 return os;
    406         } // acquire
    407401} // distribution
    408402
     
    411405        ostype & ?|?( ostype & os, T arg, Params rest ) {
    412406                (ostype &)(os | arg);                                                   // print first argument
    413                 sepSetCur$( os, sepGetTuple( os ) );                    // switch to tuple separator
     407                $sepSetCur( os, sepGetTuple( os ) );                    // switch to tuple separator
    414408                (ostype &)(os | rest);                                                  // print remaining arguments
    415                 sepSetCur$( os, sepGet( os ) );                                 // switch to regular separator
     409                $sepSetCur( os, sepGet( os ) );                                 // switch to regular separator
    416410                return os;
    417411        } // ?|?
     
    419413                // (ostype &)(?|?( os, arg, rest )); ends( os );
    420414                (ostype &)(os | arg);                                                   // print first argument
    421                 sepSetCur$( os, sepGetTuple( os ) );                    // switch to tuple separator
     415                $sepSetCur( os, sepGetTuple( os ) );                    // switch to tuple separator
    422416                (ostype &)(os | rest);                                                  // print remaining arguments
    423                 sepSetCur$( os, sepGet( os ) );                                 // switch to regular separator
     417                $sepSetCur( os, sepGet( os ) );                                 // switch to regular separator
    424418                ends( os );
    425419        } // ?|?
     
    448442// Default prefix for non-decimal prints is 0b, 0, 0x.
    449443#define IntegralFMTImpl( T, IFMTNP, IFMTP ) \
    450 forall( ostype & | basic_ostream( ostype ) ) { \
     444forall( ostype & | ostream( ostype ) ) { \
    451445        ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \
    452                 if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) ); \
     446                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) ); \
    453447\
    454448                if ( f.base == 'b' || f.base == 'B' ) {                 /* bespoke binary format */ \
     
    523517                return os; \
    524518        } /* ?|? */ \
    525         void ?|?( ostype & os, _Ostream_Manip(T) f ) { \
    526                 (ostype &)(os | f); ends( os ); \
    527         } /* ?|? */ \
     519        void ?|?( ostype & os, _Ostream_Manip(T) f ) { (ostype &)(os | f); ends( os ); } \
    528520} // distribution
    529521
    530 IntegralFMTImpl( signed char, "     *hh ", "     *.*hh " )
    531 IntegralFMTImpl( unsigned char, "     *hh ", "     *.*hh " )
    532 IntegralFMTImpl( signed short int, "     *h ", "     *.*h " )
    533 IntegralFMTImpl( unsigned short int, "     *h ", "     *.*h " )
    534 IntegralFMTImpl( signed int, "     * ", "     *.* " )
    535 IntegralFMTImpl( unsigned int, "     * ", "     *.* " )
    536 IntegralFMTImpl( signed long int, "     *l ", "     *.*l " )
    537 IntegralFMTImpl( unsigned long int, "     *l ", "     *.*l " )
    538 IntegralFMTImpl( signed long long int, "     *ll ", "     *.*ll " )
    539 IntegralFMTImpl( unsigned long long int, "     *ll ", "     *.*ll " )
    540 
    541 
     522IntegralFMTImpl( signed char, "%    *hh ", "%    *.*hh " )
     523IntegralFMTImpl( unsigned char, "%    *hh ", "%    *.*hh " )
     524IntegralFMTImpl( signed short int, "%    *h ", "%    *.*h " )
     525IntegralFMTImpl( unsigned short int, "%    *h ", "%    *.*h " )
     526IntegralFMTImpl( signed int, "%    * ", "%    *.* " )
     527IntegralFMTImpl( unsigned int, "%    * ", "%    *.* " )
     528IntegralFMTImpl( signed long int, "%    *l ", "%    *.*l " )
     529IntegralFMTImpl( unsigned long int, "%    *l ", "%    *.*l " )
     530IntegralFMTImpl( signed long long int, "%    *ll ", "%    *.*ll " )
     531IntegralFMTImpl( unsigned long long int, "%    *ll ", "%    *.*ll " )
     532
     533#if 0
    542534#if defined( __SIZEOF_INT128__ )
    543535// Default prefix for non-decimal prints is 0b, 0, 0x.
    544 forall( ostype & | basic_ostream( ostype ) )
     536#define IntegralFMTImpl128( T, SIGNED, CODE, IFMTNP, IFMTP ) \
     537forall( ostype & | ostream( ostype ) ) \
     538static 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 */ \
     554forall( 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
     648IntegralFMTImpl128( int128, signed, 'd', "%    *ll ", "%    *.*ll " )
     649IntegralFMTImpl128( 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.
     656forall( ostype & | ostream( ostype ) )
    545657static 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 ) {
    546658        int wd = 1;                                                                                     // f.wd is never 0 because 0 implies left-pad
     
    607719
    608720#define IntegralFMTImpl128( T ) \
    609 forall( ostype & | basic_ostream( ostype ) ) { \
     721forall( ostype & | ostream( ostype ) ) { \
    610722        ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \
    611723                _Ostream_Manip(uint64_t) fmt; \
     
    629741IntegralFMTImpl128( unsigned int128 )
    630742#endif // __SIZEOF_INT128__
     743#endif // 0
    631744
    632745// *********************************** floating point ***********************************
    633746
    634 static 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, ... ) \
     747#define PrintWithDP2( os, format, val, ... ) \
    642748        { \
    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 */ \
     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'; \
    656762                                } /* if */ \
    657763                        } /* 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] = ' '; \
    677764                } /* if */ \
    678765                fmt( os, "%s", &buf[bufbeg] ); \
     
    680767
    681768#define FloatingPointFMTImpl( T, DFMTNP, DFMTP ) \
    682 forall( 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 \
     769forall( ostype & | ostream( ostype ) ) { \
    691770        ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \
    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' */ \
     771                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) ); \
     772                char fmtstr[sizeof(DFMTP)];                                             /* sizeof includes '\0' */ \
    698773                if ( ! f.flags.pc ) memcpy( &fmtstr, DFMTNP, sizeof(DFMTNP) ); \
    699774                else memcpy( &fmtstr, DFMTP, sizeof(DFMTP) ); \
     
    709784                        fmtstr[sizeof(DFMTNP)-2] = f.base;                      /* sizeof includes '\0' */ \
    710785                        /* printf( "%g %d %s\n", f.val, f.wd, &fmtstr[star]); */ \
    711                         PrintWithDP2( os, &fmtstr[star], f.wd, f.val ) \
     786                        PrintWithDP2( os, &fmtstr[star], f.val, f.wd ) \
    712787                } else {                                                                                /* precision */ \
    713788                        fmtstr[sizeof(DFMTP)-2] = f.base;                       /* sizeof includes '\0' */ \
    714789                        /* printf( "%g %d %d %s\n", f.val, f.wd, f.pc, &fmtstr[star] ); */ \
    715                         PrintWithDP2( os, &fmtstr[star], f.wd, f.pc, f.val ) \
     790                        PrintWithDP2( os, &fmtstr[star], f.val, f.wd, f.pc ) \
    716791                } /* if */ \
    717792                return os; \
     
    721796} // distribution
    722797
    723 FloatingPointFMTImpl( double, "     * ", "     *.* " )
    724 FloatingPointFMTImpl( long double, "     *L ", "     *.*L " )
     798FloatingPointFMTImpl( double, "%    * ", "%    *.* " )
     799FloatingPointFMTImpl( long double, "%    *L ", "%    *.*L " )
    725800
    726801// *********************************** character ***********************************
    727802
    728 forall( ostype & | basic_ostream( ostype ) ) {
     803forall( ostype & | ostream( ostype ) ) {
    729804        ostype & ?|?( ostype & os, _Ostream_Manip(char) f ) {
    730805                if ( f.base != 'c' ) {                                                  // bespoke binary/octal/hex format
     
    737812                } // if
    738813
    739                 if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
     814                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    740815
    741816                #define CFMTNP "% * "
     
    759834// *********************************** C string ***********************************
    760835
    761 forall( ostype & | basic_ostream( ostype ) ) {
     836forall( ostype & | ostream( ostype ) ) {
    762837        ostype & ?|?( ostype & os, _Ostream_Manip(const char *) f ) {
    763838                if ( ! f.val ) return os;                                               // null pointer ?
     
    775850                } // if
    776851
    777                 if ( sepPrt$( os ) ) fmt( os, "%s", sepGetCur$( os ) );
     852                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    778853
    779854                #define SFMTNP "% * "
     
    807882
    808883
    809 forall( istype & | basic_istream( istype ) ) {
     884forall( istype & | istream( istype ) ) {
    810885        istype & ?|?( istype & is, bool & b ) {
    811886                char val[6];
     
    819894                return is;
    820895        } // ?|?
    821         void ?|?( istype & is, bool & b ) {
    822                 (istype &)(is | b); ends( is );
    823         } // ?|?
    824896
    825897        istype & ?|?( istype & is, char & c ) {
     
    833905                return is;
    834906        } // ?|?
    835         void ?|?( istype & is, char & c ) {
    836                 (istype &)(is | c); ends( is );
    837         } // ?|?
    838907
    839908        istype & ?|?( istype & is, signed char & sc ) {
     
    841910                return is;
    842911        } // ?|?
    843         void ?|?( istype & is, signed char & sc ) {
    844                 (istype &)(is | sc); ends( is );
    845         } // ?|?
    846912
    847913        istype & ?|?( istype & is, unsigned char & usc ) {
     
    849915                return is;
    850916        } // ?|?
    851         void ?|?( istype & is, unsigned char & usc ) {
    852                 (istype &)(is | usc); ends( is );
    853         } // ?|?
    854917
    855918        istype & ?|?( istype & is, short int & si ) {
     
    857920                return is;
    858921        } // ?|?
    859         void ?|?( istype & is, short int & si ) {
    860                 (istype &)(is | si); ends( is );
    861         } // ?|?
    862922
    863923        istype & ?|?( istype & is, unsigned short int & usi ) {
     
    865925                return is;
    866926        } // ?|?
    867         void ?|?( istype & is, unsigned short int & usi ) {
    868                 (istype &)(is | usi); ends( is );
    869         } // ?|?
    870927
    871928        istype & ?|?( istype & is, int & i ) {
     
    873930                return is;
    874931        } // ?|?
    875         void ?|?( istype & is, int & i ) {
    876                 (istype &)(is | i); ends( is );
    877         } // ?|?
    878932
    879933        istype & ?|?( istype & is, unsigned int & ui ) {
     
    881935                return is;
    882936        } // ?|?
    883         void ?|?( istype & is, unsigned int & ui ) {
    884                 (istype &)(is | ui); ends( is );
    885         } // ?|?
    886937
    887938        istype & ?|?( istype & is, long int & li ) {
     
    889940                return is;
    890941        } // ?|?
    891         void ?|?( istype & is, long int & li ) {
    892                 (istype &)(is | li); ends( is );
    893         } // ?|?
    894942
    895943        istype & ?|?( istype & is, unsigned long int & ulli ) {
     
    897945                return is;
    898946        } // ?|?
    899         void ?|?( istype & is, unsigned long int & ulli ) {
    900                 (istype &)(is | ulli); ends( is );
    901         } // ?|?
    902947
    903948        istype & ?|?( istype & is, long long int & lli ) {
     
    905950                return is;
    906951        } // ?|?
    907         void ?|?( istype & is, long long int & lli ) {
    908                 (istype &)(is | lli); ends( is );
    909         } // ?|?
    910952
    911953        istype & ?|?( istype & is, unsigned long long int & ulli ) {
     
    913955                return is;
    914956        } // ?|?
    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 ) {
     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 ) {
    928964                char s[40];
    929965                bool sign = false;
     
    932968                // If the input is too large, the value returned is undefined. If there is no input, no value is returned
    933969                if ( fmt( is, "%39[0-9]%*[0-9]", s ) == 1 ) {   // take first 39 characters, ignore remaining
    934                         ullli = 0;
     970                        ui128 = 0;
    935971                        for ( unsigned int i = 0; s[i] != '\0'; i += 1 ) {
    936                                 ullli = ullli * 10 + s[i] - '0';
     972                                ui128 = ui128 * 10 + s[i] - '0';
    937973                        } // for
    938                         if ( sign ) ullli = -ullli;
     974                        if ( sign ) ui128 = -ui128;
    939975                } else if ( sign ) ungetc( is, '-' );                   // return minus when no digits
    940976                return is;
    941977        } // ?|?
    942         void ?|?( istype & is, unsigned int128 & ullli ) {
    943                 (istype &)(is | ullli); ends( is );
    944         } // ?|?
    945         #endif // __SIZEOF_INT128__
     978#endif // __SIZEOF_INT128__
    946979
    947980        istype & ?|?( istype & is, float & f ) {
     
    949982                return is;
    950983        } // ?|?
    951         void ?|?( istype & is, float & f ) {
    952                 (istype &)(is | f); ends( is );
    953         } // ?|?
    954984
    955985        istype & ?|?( istype & is, double & d ) {
     
    957987                return is;
    958988        } // ?|?
    959         void ?|?( istype & is, double & d ) {
    960                 (istype &)(is | d); ends( is );
    961         } // ?|?
    962989
    963990        istype & ?|?( istype & is, long double & ld ) {
     
    965992                return is;
    966993        } // ?|?
    967         void ?|?( istype & is, long double & ld ) {
    968                 (istype &)(is | ld); ends( is );
    969         } // ?|?
     994
    970995
    971996        istype & ?|?( istype & is, float _Complex & fc ) {
     
    9751000                return is;
    9761001        } // ?|?
    977         void ?|?( istype & is, float _Complex & fc ) {
    978                 (istype &)(is | fc); ends( is );
    979         } // ?|?
    9801002
    9811003        istype & ?|?( istype & is, double _Complex & dc ) {
     
    9851007                return is;
    9861008        } // ?|?
    987         void ?|?( istype & is, double _Complex & dc ) {
    988                 (istype &)(is | dc); ends( is );
    989         } // ?|?
    9901009
    9911010        istype & ?|?( istype & is, long double _Complex & ldc ) {
     
    9951014                return is;
    9961015        } // ?|?
    997         void ?|?( istype & is, long double _Complex & ldc ) {
    998                 (istype &)(is | ldc); ends( is );
    999         } // ?|?
    10001016
    10011017        // istype & ?|?( istype & is, const char fmt[] ) {
     
    10041020        // } // ?|?
    10051021
    1006         istype & ?|?( istype & is, char s[] ) {
     1022        istype & ?|?( istype & is, char * s ) {
    10071023                fmt( is, "%s", s );
    10081024                return is;
    1009         } // ?|?
    1010         void ?|?( istype & is, char s[] ) {
    1011                 (istype &)(is | s); ends( is );
    10121025        } // ?|?
    10131026
     
    10161029                return manip( is );
    10171030        } // ?|?
    1018         void ?|?( istype & is, istype & (* manip)( istype & ) ) {
    1019                 manip( is ); ends( is );
    1020         } // ?|?
    10211031
    10221032        istype & nl( istype & is ) {
     
    10361046} // distribution
    10371047
    1038 forall( istype & | istream( istype ) ) {
    1039         istype & acquire( istype & is ) {
    1040                 acquire( is );                                                                  // call void returning
    1041                 return is;
    1042         } // acquire
    1043 } // distribution
    1044 
    10451048// *********************************** manipulators ***********************************
    10461049
    1047 forall( 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 );
     1050forall( istype & | istream( istype ) )
     1051istype & ?|?( 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 );
    10781070                fmt( is, fmtstr, f.s );
    10791071                return is;
    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
     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
     1085forall( istype & | istream( istype ) )
     1086istype & ?|?( istype & is, _Istream_Char f ) {
     1087        fmt( is, "%*c" );                                                                       // argument variable unused
     1088        return is;
     1089} // ?|?
    10931090
    10941091#define InputFMTImpl( T, CODE ) \
    1095 forall( 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
     1092forall( istype & | istream( istype ) ) \
     1093istype & ?|?( 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} // ?|?
    11121105
    11131106InputFMTImpl( signed char, "hhi" )
     
    11261119InputFMTImpl( long double, "Lf" )
    11271120
    1128 forall( 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
     1121forall( istype & | istream( istype ) )
     1122istype & ?|?( 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
     1132forall( istype & | istream( istype ) )
     1133istype & ?|?( 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
     1143forall( istype & | istream( istype ) )
     1144istype & ?|?( 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} // ?|?
    11681153
    11691154// Local Variables: //
Note: See TracChangeset for help on using the changeset viewer.