Changeset 3c573e9


Ignore:
Timestamp:
Jun 4, 2019, 6:34:15 PM (2 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
arm-eh, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr
Children:
9be45a2
Parents:
0161ddf
Message:

first draft of output manipulators and start input manipulators

Location:
libcfa/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/iostream.cfa

    r0161ddf r3c573e9  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue May 21 13:01:26 2019
    13 // Update Count     : 674
     12// Last Modified On : Tue Jun  4 17:32:34 2019
     13// Update Count     : 761
    1414//
    1515
     
    2020#include <stdbool.h>                                                                    // true/false
    2121//#include <string.h>                                                                   // strlen, strcmp
     22extern size_t strlen (const char *__s) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1)));
    2223extern int strcmp (const char *__s1, const char *__s2) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2)));
    23 extern size_t strlen (const char *__s) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1)));
     24extern char *strcpy (char *__restrict __dest, const char *__restrict __src) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
     25extern void *memcpy (void *__restrict __dest, const void *__restrict __src, size_t __n) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
    2426#include <float.h>                                                                              // DBL_DIG, LDBL_DIG
    2527#include <math.h>                                                                               // isfinite
    2628#include <complex.h>                                                                    // creal, cimag
    27 }
     29} // extern "C"
    2830
    2931forall( dtype ostype | ostream( ostype ) ) {
     
    198200                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    199201//              os | crealf( fc ) | nonl;
    200                 float f = crealf( fc );
    201                 PrintWithDP( os, "%g", f );
    202                 f = cimagf( fc );
    203                 PrintWithDP( os, "%+g", f );
     202                PrintWithDP( os, "%g", crealf( fc ) );
     203                PrintWithDP( os, "%+g", cimagf( fc ) );
    204204                fmt( os, "i" );
    205205                return os;
     
    212212                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    213213//              os | creal( dc ) | nonl;
    214                 double d = creal( dc );
    215                 PrintWithDP( os, "%.*lg", d, DBL_DIG );
    216                 d = cimag( dc );
    217                 PrintWithDP( os, "%+.*lg", d, DBL_DIG );
     214                PrintWithDP( os, "%.*lg", creal( dc ), DBL_DIG );
     215                PrintWithDP( os, "%+.*lg", cimag( dc ), DBL_DIG );
    218216                fmt( os, "i" );
    219217                return os;
     
    226224                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    227225//              os | creall( ldc ) || nonl;
    228                 long double ld = creall( ldc );
    229                 PrintWithDP( os, "%.*Lg", ld, LDBL_DIG );
    230                 ld = cimagl( ldc );
    231                 PrintWithDP( os, "%+.*Lg", ld, LDBL_DIG );
     226                PrintWithDP( os, "%.*Lg", creall( ldc ), LDBL_DIG );
     227                PrintWithDP( os, "%+.*Lg", cimagl( ldc ), LDBL_DIG );
    232228                fmt( os, "i" );
    233229                return os;
     
    395391} // distribution
    396392
     393
     394//*********************************** Integral ***********************************
     395
     396static const char * shortbin[] = { "0", "1", "10", "11", "100", "101", "110", "111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111" };
     397static const char * longbin[]  = { "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111" };
     398
     399// Default prefix for non-decimal prints is 0b, 0, 0x.
     400#define IntegralFMTImpl( T, CODE, IFMTNP, IFMTP ) \
     401forall( dtype ostype | ostream( ostype ) ) { \
     402        ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \
     403                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) ); \
     404\
     405                if ( f.base == 'b' || f.base == 'B' ) {                 /* bespoke binary format */ \
     406                        int bits;                                                                                                       \
     407                        if ( f.val == (T){0} ) bits = 1;                        /* force at least one bit to print */ \
     408                        else bits = sizeof(long long int) * 8 - __builtin_clzll( f.val ); /* position of most significant bit */ \
     409                        bits = bits > sizeof(f.val) * 8 ? sizeof(f.val) * 8 : bits; \
     410                        int spaces = f.wd - bits;                                       /* can be negative */ \
     411                        if ( ! f.flags.nobsdp ) { spaces -= 2; }        /* base prefix takes space */ \
     412                        /* printf( "%d %d\n", bits, spaces ); */ \
     413                        if ( ! f.flags.left ) {                                         /* right justified ? */ \
     414                                /* Note, base prefix then zero padding or spacing then prefix. */ \
     415                                if ( f.flags.pad0 || f.flags.pc ) { \
     416                                        if ( ! f.flags.nobsdp ) { fmt( os, "0%c", f.base ); } \
     417                                        if ( f.flags.pc ) spaces = f.pc - bits; \
     418                                        if ( spaces > 0 ) fmt( os, "%0*d", spaces, 0 ); /* zero pad */ \
     419                                } else { \
     420                                        if ( spaces > 0 ) fmt( os, "%*s", spaces, " " ); /* space pad */ \
     421                                        if ( ! f.flags.nobsdp ) { fmt( os, "0%c", f.base ); } \
     422                                } /* if */ \
     423                        } else if ( ! f.flags.nobsdp ) { \
     424                                fmt( os, "0%c", f.base ); \
     425                        } /* if */ \
     426                        int shift = (bits - 1) / 4 * 4; /* floor( bits - 1, 4 ) */ \
     427                        typeof( f.val ) temp = f.val; \
     428                        fmt( os, "%s", shortbin[(temp >> shift) & 0xf] ); \
     429                        for () { \
     430                                shift -= 4; \
     431                          if ( shift < 0 ) break; \
     432                                temp = f.val; \
     433                                fmt( os, "%s", longbin[(temp >> shift) & 0xf] ); \
     434                        } /* for */ \
     435                        if ( f.flags.left && spaces > 0 ) fmt( os, "%*s", spaces, " " ); \
     436                        return os; \
     437                } /* if  */ \
     438\
     439                char fmtstr[sizeof(IFMTP)];                                             /* sizeof includes '\0' */ \
     440                if ( ! f.flags.pc ) memcpy( &fmtstr, IFMTNP, sizeof(IFMTNP) ); \
     441                else memcpy( &fmtstr, IFMTP, sizeof(IFMTP) ); \
     442                int star = 4;                                                                   /* position before first '*' */ \
     443\
     444                /* Insert flags into spaces before '*', from right to left. */ \
     445                if ( ! f.flags.nobsdp ) { fmtstr[star] = '#'; star -= 1; } \
     446                if ( f.flags.left ) { fmtstr[star] = '-'; star -= 1; } \
     447                if ( f.flags.sign && f.base == CODE ) { fmtstr[star] = '+'; star -= 1; } \
     448                if ( f.flags.pad0 && ! f.flags.pc ) { fmtstr[star] = '0'; star -= 1; } \
     449                fmtstr[star] = '%'; \
     450\
     451                if ( ! f.flags.pc ) {                                                   /* no precision */ \
     452                        /* printf( "%s\n", &fmtstr[star] ); */ \
     453                        fmtstr[sizeof(IFMTNP)-2] = f.base;                      /* sizeof includes '\0' */ \
     454                        fmt( os, &fmtstr[star], f.wd, f.val ); \
     455                } else {                                                                                /* precision */ \
     456                        fmtstr[sizeof(IFMTP)-2] = f.base;                       /* sizeof includes '\0' */ \
     457                        /* printf( "%s\n", &fmtstr[star] ); */ \
     458                        fmt( os, &fmtstr[star], f.wd, f.pc, f.val ); \
     459                } /* if */ \
     460                return os; \
     461        } /* ?|? */ \
     462        void ?|?( ostype & os, _Ostream_Manip(T) f ) { (ostype &)(os | f); nl( os ); } \
     463} // distribution
     464
     465IntegralFMTImpl( signed char, 'd', "%    *hh ", "%    *.*hh " )
     466IntegralFMTImpl( unsigned char, 'u', "%    *hh ", "%    *.*hh " )
     467IntegralFMTImpl( signed short int, 'd', "%    *h ", "%    *.*h " )
     468IntegralFMTImpl( unsigned short int, 'u', "%    *h ", "%    *.*h " )
     469IntegralFMTImpl( signed int, 'd', "%    * ", "%    *.* " )
     470IntegralFMTImpl( unsigned int, 'u', "%    * ", "%    *.* " )
     471IntegralFMTImpl( signed long int, 'd', "%    *l ", "%    *.*l " )
     472IntegralFMTImpl( unsigned long int, 'u', "%    *l ", "%    *.*l " )
     473IntegralFMTImpl( signed long long int, 'd', "%    *ll ", "%    *.*ll " )
     474IntegralFMTImpl( unsigned long long int, 'u', "%    *ll ", "%    *.*ll " )
     475
     476//*********************************** Floating Point ***********************************
     477
     478#define PrintWithDP2( os, format, val, ... ) \
     479        { \
     480                enum { size = 48 }; \
     481                char buf[size]; \
     482                int bufbeg = 0, i, len = snprintf( buf, size, format, ##__VA_ARGS__, val ); \
     483                if ( isfinite( val ) && (f.base != 'g' || f.pc != 0) ) { /* if number, print decimal point */ \
     484                        for ( i = 0; i < len && buf[i] != '.' && buf[i] != 'e' && buf[i] != 'E'; i += 1 ); /* decimal point or scientific ? */ \
     485                        if ( i == len && ! f.flags.nobsdp ) { \
     486                                if ( ! f.flags.left ) { \
     487                                        buf[i] = '.'; buf[i + 1] = '\0'; \
     488                                        if ( buf[0] == ' ' ) bufbeg = 1; /* decimal point within width */ \
     489                                } else { \
     490                                        for ( i = 0; i < len && buf[i] != ' '; i += 1 ); /* trailing blank ? */ \
     491                                        buf[i] = '.'; \
     492                                        if ( i == len ) buf[i + 1] = '\0'; \
     493                                } /* if */ \
     494                        } /* if */ \
     495                } /* if */ \
     496                fmt( os, "%s", &buf[bufbeg] ); \
     497        }
     498
     499#define FloatingPointFMTImpl( T, DFMTNP, DFMTP ) \
     500forall( dtype ostype | ostream( ostype ) ) { \
     501        ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \
     502                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) ); \
     503                char fmtstr[sizeof(DFMTP)];                                             /* sizeof includes '\0' */ \
     504                if ( ! f.flags.pc ) memcpy( &fmtstr, DFMTNP, sizeof(DFMTNP) ); \
     505                else memcpy( &fmtstr, DFMTP, sizeof(DFMTP) ); \
     506                int star = 4;                                                                   /* position before first '*' */ \
     507\
     508                /* Insert flags into spaces before '*', from right to left. */ \
     509                if ( f.flags.left ) { fmtstr[star] = '-'; star -= 1; } \
     510                if ( f.flags.sign ) { fmtstr[star] = '+'; star -= 1; } \
     511                if ( f.flags.pad0 ) { fmtstr[star] = '0'; star -= 1; } \
     512                fmtstr[star] = '%'; \
     513\
     514                if ( ! f.flags.pc ) {                                                   /* no precision */ \
     515                        fmtstr[sizeof(DFMTNP)-2] = f.base;                      /* sizeof includes '\0' */ \
     516                        /* printf( "%g %d %s\n", f.val, f.wd, &fmtstr[star]); */ \
     517                        PrintWithDP2( os, &fmtstr[star], f.val, f.wd ) \
     518                } else {                                                                                /* precision */ \
     519                        fmtstr[sizeof(DFMTP)-2] = f.base;                       /* sizeof includes '\0' */ \
     520                        /* printf( "%g %d %d %s\n", f.val, f.wd, f.pc, &fmtstr[star] ); */ \
     521                        PrintWithDP2( os, &fmtstr[star], f.val, f.wd, f.pc ) \
     522                } /* if */ \
     523                return os; \
     524        } /* ?|? */ \
     525        void ?|?( ostype & os, _Ostream_Manip(T) f ) { (ostype &)(os | f); nl( os ); } \
     526} // distribution
     527
     528FloatingPointFMTImpl( double, "%    * ", "%    *.* " )
     529FloatingPointFMTImpl( long double, "%    *L ", "%    *.*L " )
     530
     531//*********************************** Character ***********************************
     532
     533forall( dtype ostype | ostream( ostype ) ) {
     534        ostype & ?|?( ostype & os, _Ostream_Manip(char) f ) {
     535                if ( f.base != 'c' ) {                                                          // bespoke binary/octal/hex format
     536                        _Ostream_Manip(unsigned char) fmtuc @= { f.val, f.wd, f.pc, f.base, {'\0'} };
     537                        fmtuc.flags.pc = f.flags.pc;
     538                        fmtuc.flags.nobsdp = f.flags.nobsdp;
     539//                      os | fmtuc | nonl;
     540                        (ostype &)(os | fmtuc);
     541                        return os;
     542                } // if
     543
     544                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     545
     546                #define CFMTNP "% * "
     547                char fmtstr[sizeof(CFMTNP)];                                            // sizeof includes '\0'
     548                memcpy( &fmtstr, CFMTNP, sizeof(CFMTNP) );
     549                int star = 1;                                                                           // position before first '*'
     550
     551                // Insert flags into spaces before '*', from right to left.
     552                if ( f.flags.left ) { fmtstr[star] = '-'; star -= 1; }
     553                fmtstr[star] = '%';
     554
     555                fmtstr[sizeof(CFMTNP)-2] = f.base;                                      // sizeof includes '\0'
     556                // printf( "%d %s\n", f.wd, &fmtstr[star] );
     557                fmt( os, &fmtstr[star], f.wd, f.val );
     558                return os;
     559        } // ?|?
     560        void ?|?( ostype & os, _Ostream_Manip(char) f ) { (ostype &)(os | f); nl( os ); }
     561} // distribution
     562
     563//*********************************** C String ***********************************
     564
     565forall( dtype ostype | ostream( ostype ) ) {
     566        ostype & ?|?( ostype & os, _Ostream_Manip(const char *) f ) {
     567                if ( ! f.val ) return os;                                               // null pointer ?
     568
     569                if ( f.base != 's' ) {                                                  // bespoke binary/octal/hex format
     570                        _Ostream_Manip(unsigned char) fmtuc @= { 0, f.wd, f.pc, f.base, {'\0'} };
     571                        fmtuc.flags.pc = f.flags.pc;
     572                        fmtuc.flags.nobsdp = f.flags.nobsdp;
     573                        for ( unsigned int i = 0; f.val[i] != '\0'; i += 1 ) {
     574                                fmtuc.val = f.val[i];
     575//                              os | fmtuc | nonl;
     576                                (ostype &)(os | fmtuc);
     577                        } // for
     578                        return os;
     579                } // if
     580
     581                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     582
     583                #define SFMTNP "% * "
     584                #define SFMTP "% *.* "
     585                char fmtstr[sizeof(SFMTP)];                                             // sizeof includes '\0'
     586                if ( ! f.flags.pc ) memcpy( &fmtstr, SFMTNP, sizeof(SFMTNP) );
     587                else memcpy( &fmtstr, SFMTP, sizeof(SFMTP) );
     588                int star = 1;                                                                   // position before first '*'
     589
     590                // Insert flags into spaces before '*', from right to left.
     591                if ( f.flags.left ) { fmtstr[star] = '-'; star -= 1; }
     592                fmtstr[star] = '%';
     593
     594                if ( ! f.flags.pc ) {                                                   // no precision
     595                        // printf( "%d %s\n", f.wd, &fmtstr[star] );
     596                        fmtstr[sizeof(SFMTNP)-2] = f.base;                      // sizeof includes '\0'
     597                        fmt( os, &fmtstr[star], f.wd, f.val );
     598                } else {                                                                                // precision
     599                        fmtstr[sizeof(SFMTP)-2] = f.base;                       // sizeof includes '\0'
     600                        // printf( "%d %d %s\n", f.wd, f.pc, &fmtstr[star] );
     601                        fmt( os, &fmtstr[star], f.wd, f.pc, f.val );
     602                } // if
     603                return os;
     604        } // ?|?
     605        void ?|?( ostype & os, _Ostream_Manip(const char *) f ) { (ostype &)(os | f); nl( os ); }
     606} // distribution
     607
    397608//---------------------------------------
    398609
     
    410621} // distribution
    411622
    412 //---------------------------------------
     623
     624//*********************************** Istream ***********************************
     625
    413626
    414627forall( dtype istype | istream( istype ) ) {
     
    437650
    438651        istype & ?|?( istype & is, signed char & sc ) {
    439                 fmt( is, "%hhd", &sc );
     652                fmt( is, "%hhi", &sc );
    440653                return is;
    441654        } // ?|?
    442655
    443656        istype & ?|?( istype & is, unsigned char & usc ) {
    444                 fmt( is, "%hhu", &usc );
     657                fmt( is, "%hhi", &usc );
    445658                return is;
    446659        } // ?|?
    447660
    448661        istype & ?|?( istype & is, short int & si ) {
    449                 fmt( is, "%hd", &si );
     662                fmt( is, "%hi", &si );
    450663                return is;
    451664        } // ?|?
    452665
    453666        istype & ?|?( istype & is, unsigned short int & usi ) {
    454                 fmt( is, "%hu", &usi );
     667                fmt( is, "%hi", &usi );
    455668                return is;
    456669        } // ?|?
    457670
    458671        istype & ?|?( istype & is, int & i ) {
    459                 fmt( is, "%d", &i );
     672                fmt( is, "%i", &i );
    460673                return is;
    461674        } // ?|?
    462675
    463676        istype & ?|?( istype & is, unsigned int & ui ) {
    464                 fmt( is, "%u", &ui );
     677                fmt( is, "%i", &ui );
    465678                return is;
    466679        } // ?|?
    467680
    468681        istype & ?|?( istype & is, long int & li ) {
    469                 fmt( is, "%ld", &li );
     682                fmt( is, "%li", &li );
    470683                return is;
    471684        } // ?|?
    472685
    473686        istype & ?|?( istype & is, unsigned long int & ulli ) {
    474                 fmt( is, "%lu", &ulli );
     687                fmt( is, "%li", &ulli );
    475688                return is;
    476689        } // ?|?
    477690
    478691        istype & ?|?( istype & is, long long int & lli ) {
    479                 fmt( is, "%lld", &lli );
     692                fmt( is, "%lli", &lli );
    480693                return is;
    481694        } // ?|?
    482695
    483696        istype & ?|?( istype & is, unsigned long long int & ulli ) {
    484                 fmt( is, "%llu", &ulli );
     697                fmt( is, "%lli", &ulli );
    485698                return is;
    486699        } // ?|?
     
    505718        istype & ?|?( istype & is, float _Complex & fc ) {
    506719                float re, im;
    507                 fmt( is, "%g%gi", &re, &im );
     720                fmt( is, "%f%fi", &re, &im );
    508721                fc = re + im * _Complex_I;
    509722                return is;
     
    561774} // cstr
    562775
     776#if 0
     777forall( dtype istype | istream( istype ) )
     778istype & ?|?( istype & is, _Istream_skip skip ) {
     779        fmt( is, skip.s, "" );                                                          // no input arguments
     780        return is;
     781} // skip
     782
     783forall( dtype istype | istream( istype ) )
     784istype & ?|?( istype & is, _Istream_incl incl ) {
     785        size_t len = strlen( incl.scanset ) + 4;                        // extras: "%[]\0"
     786        char fmtstr[len];
     787        fmtstr[0] = '%'; fmtstr[1] = '[';
     788        strcpy( &fmtstr[2], incl.scanset );                                     // after '[', copy includes '\0'
     789        fmtstr[len - 2] = ']'; fmtstr[len - 1] = '\0';
     790        fmt( is, fmtstr, incl.s );
     791        return is;
     792} // incl
     793
     794forall( dtype istype | istream( istype ) )
     795istype & ?|?( istype & is, _Istream_excl excl ) {
     796        size_t len = strlen( excl.scanset );
     797        char fmtstr[len+5];
     798        fmtstr[0] = '%'; fmtstr[1] = '['; fmtstr[2] = '^';
     799        strcpy( &fmtstr[3], excl.scanset );                                     // after '^', copy includes '\0'
     800        fmtstr[len - 2] = ']'; fmtstr[len - 1] = '\0';
     801        fmt( is, fmtstr, excl.s );
     802        return is;
     803} // excl
     804
     805forall( dtype istype | istream( istype ) )
     806istype & ?|?( istype & is, _Istream_cstr cstr ) {
     807        fmt( is, "%s", cstr.s );
     808        return is;
     809} // cstr
     810
     811_Istream_cstrW cstr( char * s, int size ) { return (_Istream_cstrW){ s, size }; }
     812forall( dtype istype | istream( istype ) )
     813istype & ?|?( istype & is, _Istream_cstrW cstr ) {
     814        enum { size = 16 };
     815        char fmtstr[size];
     816        sprintf( fmtstr, "%%%ds", cstr.size );
     817        fmt( is, fmtstr, cstr.s );
     818        return is;
     819} // cstr
     820
     821forall( dtype istype | istream( istype ) ) istype & ?|?( istype &, _Istream_Cstr ) {
     822       
     823}
     824
     825//*********************************** Manipulators ***********************************
     826
     827#define InputFMTImpl( T, CODE ) \
     828forall( dtype istype | istream( istype ) ) \
     829istype & ?|?( istype & is, _Istream_Manip(T) f ) { \
     830        enum { size = 16 }; \
     831        char fmtstr[size]; \
     832        if ( f.wd == -1 ) { \
     833                snprintf( fmtstr, size, "%%%s%s", f.ignore ? "*" : "", CODE ); \
     834        } else { \
     835                snprintf( fmtstr, size, "%%%s%d%s", f.ignore ? "*" : "", f.wd, CODE ); \
     836        } /* if */ \
     837        /* printf( "%d %s %p\n", f.wd, fmtstr, &f.val ); */ \
     838        fmt( is, fmtstr, &f.val ); \
     839        return is; \
     840} /* ?|? */
     841
     842InputFMTImpl( char, "c" )
     843InputFMTImpl( signed char, "hhi" )
     844InputFMTImpl( unsigned char, "hhi" )
     845InputFMTImpl( signed short int, "hi" )
     846InputFMTImpl( unsigned short int, "hi" )
     847InputFMTImpl( signed int, "i" )
     848InputFMTImpl( unsigned int, "i" )
     849InputFMTImpl( signed long int, "li" )
     850InputFMTImpl( unsigned long int, "li" )
     851InputFMTImpl( signed long long int, "lli" )
     852InputFMTImpl( unsigned long long int, "lli" )
     853
     854InputFMTImpl( float, "f" )
     855InputFMTImpl( double, "lf" )
     856InputFMTImpl( long double, "Lf" )
     857
     858InputFMTImpl( float _Complex, "ff" )
     859InputFMTImpl( double _Complex, "lf" )
     860InputFMTImpl( long double _Complex, "Lf" )
     861#endif // 0
     862
    563863// Local Variables: //
    564864// tab-width: 4 //
  • libcfa/src/iostream.hfa

    r0161ddf r3c573e9  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // iostream --
     7// iostream.hfa --
    88//
    99// Author           : Peter A. Buhr
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat May 11 10:31:27 2019
    13 // Update Count     : 232
     12// Last Modified On : Tue Jun  4 17:33:43 2019
     13// Update Count     : 286
    1414//
    1515
     
    1717
    1818#include "iterator.hfa"
     19
     20
     21//*********************************** Ostream ***********************************
     22
    1923
    2024trait ostream( dtype ostype ) {
     
    146150} // distribution
    147151
    148 //---------------------------------------
     152//*********************************** Manipulators ***********************************
     153
     154forall( otype T )
     155struct _Ostream_Manip {
     156        T val;                                                                                          // polymorphic base-type
     157        unsigned char wd, pc;                                                           // width, precision
     158        char base;                                                                                      // numeric base / floating-point style
     159        union {
     160                unsigned char all;
     161                struct {
     162                        unsigned char pc:1;                                                     // precision specified
     163                        unsigned char left:1;                                           // left justify
     164                        unsigned char nobsdp:1;                                         // base prefix / decimal point
     165                        unsigned char sign:1;                                           // plus / minus sign
     166                        unsigned char pad0:1;                                           // zero pad
     167                } flags;
     168        };
     169}; // _Ostream_Manip
     170
     171//*********************************** Integral ***********************************
     172
     173#define IntegralFMTDecl( T, CODE ) \
     174static inline { \
     175        _Ostream_Manip(T) bin( T v ) { return (_Ostream_Manip(T))@{ v, 1, 0, 'b', { .all : 0 } }; } \
     176        _Ostream_Manip(T) oct( T v ) { return (_Ostream_Manip(T))@{ v, 1, 0, 'o', { .all : 0 } }; } \
     177        _Ostream_Manip(T) hex( T v ) { return (_Ostream_Manip(T))@{ v, 1, 0, 'x', { .all : 0 } }; } \
     178        _Ostream_Manip(T) wd( unsigned char w, T v ) { return (_Ostream_Manip(T))@{ v, w, 0, CODE, { .all : 0 } }; } \
     179        _Ostream_Manip(T) wd( unsigned char w, unsigned char p, T v ) { return (_Ostream_Manip(T))@{ v, w, p, CODE, { .flags.pc : true } }; } \
     180        _Ostream_Manip(T) & wd( unsigned char w, _Ostream_Manip(T) & fmt ) with(fmt) { wd = w; return fmt; } \
     181        _Ostream_Manip(T) & wd( unsigned char w, unsigned char p, _Ostream_Manip(T) & fmt ) with(fmt) { wd = w; pc = p; flags.pc = true; return fmt; } \
     182        _Ostream_Manip(T) & left( _Ostream_Manip(T) & fmt ) { fmt.flags.left = true; return fmt; } \
     183        _Ostream_Manip(T) & upcase( _Ostream_Manip(T) & fmt ) { if ( fmt.base == 'x' || fmt.base == 'b' ) fmt.base -= 32; /* upper case */ return fmt; } \
     184        _Ostream_Manip(T) & nobase( _Ostream_Manip(T) & fmt ) { fmt.flags.nobsdp = true; return fmt; } \
     185        _Ostream_Manip(T) & pad0( _Ostream_Manip(T) & fmt ) { fmt.flags.pad0 = true; return fmt; } \
     186        _Ostream_Manip(T) sign( T v ) { return (_Ostream_Manip(T))@{ v, 1, 0, CODE, { .flags.sign : true } }; } \
     187        _Ostream_Manip(T) & sign( _Ostream_Manip(T) & fmt ) { fmt.flags.sign = true; return fmt; } \
     188} \
     189forall( dtype ostype | ostream( ostype ) ) { \
     190        ostype & ?|?( ostype & os, _Ostream_Manip(T) f ); \
     191        void ?|?( ostype & os, _Ostream_Manip(T) f ); \
     192}
     193
     194IntegralFMTDecl( signed char, 'd' )
     195IntegralFMTDecl( unsigned char, 'u' )
     196IntegralFMTDecl( signed short int, 'd' )
     197IntegralFMTDecl( unsigned short int, 'u' )
     198IntegralFMTDecl( signed int, 'd' )
     199IntegralFMTDecl( unsigned int, 'u' )
     200IntegralFMTDecl( signed long int, 'd' )
     201IntegralFMTDecl( unsigned long int, 'u' )
     202IntegralFMTDecl( signed long long int, 'd' )
     203IntegralFMTDecl( unsigned long long int, 'u' )
     204
     205//*********************************** Floating Point ***********************************
     206
     207// Default suffix for values with no fraction is "."
     208#define FloatingPointFMTDecl( T ) \
     209static inline { \
     210        _Ostream_Manip(T) sci( T v ) { return (_Ostream_Manip(T))@{ v, 1, 0, 'e', { .all : 0 } }; } \
     211        _Ostream_Manip(T) hex( T v ) { return (_Ostream_Manip(T))@{ v, 1, 0, 'a', { .all : 0 } }; } \
     212        _Ostream_Manip(T) wd( unsigned char w, T v ) { return (_Ostream_Manip(T))@{ v, w, 0, 'f', { .all : 0 } }; } \
     213        _Ostream_Manip(T) wd( unsigned char w, unsigned char p, T v ) { return (_Ostream_Manip(T))@{ v, w, p, 'f', { .flags.pc : true } }; } \
     214        _Ostream_Manip(T) ws( unsigned char w, unsigned char p, T v ) { return (_Ostream_Manip(T))@{ v, w, p, 'g', { .flags.pc : true } }; } \
     215        _Ostream_Manip(T) & wd( unsigned char w, _Ostream_Manip(T) & fmt ) with(fmt) { wd = w; return fmt; } \
     216        _Ostream_Manip(T) & wd( unsigned char w, unsigned char p, _Ostream_Manip(T) & fmt ) with(fmt) { wd = w; pc = p; flags.pc = true; return fmt; } \
     217        _Ostream_Manip(T) & left( _Ostream_Manip(T) & fmt ) { fmt.flags.left = true; return fmt; } \
     218        _Ostream_Manip(T) upcase( T v ) { return (_Ostream_Manip(T))@{ v, 1, 0, 'G', { .all : 0 } }; } \
     219        _Ostream_Manip(T) & upcase( _Ostream_Manip(T) & fmt ) { fmt.base -= 32; /* upper case */ return fmt; } \
     220        _Ostream_Manip(T) & pad0( _Ostream_Manip(T) & fmt ) { fmt.flags.pad0 = true; return fmt; } \
     221        _Ostream_Manip(T) sign( T v ) { return (_Ostream_Manip(T))@{ v, 1, 0, 'g', { .flags.sign : true } }; } \
     222        _Ostream_Manip(T) & sign( _Ostream_Manip(T) & fmt ) { fmt.flags.sign = true; return fmt; } \
     223        _Ostream_Manip(T) nodp( T v ) { return (_Ostream_Manip(T))@{ v, 1, 0, 'g', { .flags.nobsdp : true } }; } \
     224        _Ostream_Manip(T) & nodp( _Ostream_Manip(T) & fmt ) { fmt.flags.nobsdp = true; return fmt; } \
     225} \
     226forall( dtype ostype | ostream( ostype ) ) { \
     227        ostype & ?|?( ostype & os, _Ostream_Manip(T) f ); \
     228        void ?|?( ostype & os, _Ostream_Manip(T) f ); \
     229}
     230
     231FloatingPointFMTDecl( double )
     232FloatingPointFMTDecl( long double )
     233
     234//*********************************** Character ***********************************
     235
     236static inline {
     237        _Ostream_Manip(char) bin( char v ) { return (_Ostream_Manip(char))@{ v, 1, 0, 'b', { .all : 0 } }; }
     238        _Ostream_Manip(char) oct( char v ) { return (_Ostream_Manip(char))@{ v, 1, 0, 'o', { .all : 0 } }; }
     239        _Ostream_Manip(char) hex( char v ) { return (_Ostream_Manip(char))@{ v, 1, 0, 'x', { .all : 0 } }; }
     240        _Ostream_Manip(char) wd( unsigned char w, char v ) { return (_Ostream_Manip(char))@{ v, w, 0, 'c', { .all : 0 } }; }
     241        _Ostream_Manip(char) & wd( unsigned char w, _Ostream_Manip(char) & fmt ) with(fmt) { wd = w; return fmt; }
     242        _Ostream_Manip(char) & left( _Ostream_Manip(char) & fmt ) { fmt.flags.left = true; return fmt; }
     243        _Ostream_Manip(char) & upcase( _Ostream_Manip(char) & fmt ) { if ( fmt.base == 'x' || fmt.base == 'b' ) fmt.base -= 32; /* upper case */ return fmt; }
     244        _Ostream_Manip(char) & nobase( _Ostream_Manip(char) & fmt ) { fmt.flags.nobsdp = true; return fmt; }
     245} // distribution
     246forall( dtype ostype | ostream( ostype ) ) {
     247        ostype & ?|?( ostype & os, _Ostream_Manip(char) f );
     248        void ?|?( ostype & os, _Ostream_Manip(char) f );
     249}
     250
     251//*********************************** C String ***********************************
     252
     253static inline {
     254        _Ostream_Manip(const char *) bin( const char * v ) { return (_Ostream_Manip(const char *))@{ v, 1, 0, 'b', { .all : 0 } }; }
     255        _Ostream_Manip(const char *) oct( const char * v ) { return (_Ostream_Manip(const char *))@{ v, 1, 0, 'o', { .all : 0 } }; }
     256        _Ostream_Manip(const char *) hex( const char * v ) { return (_Ostream_Manip(const char *))@{ v, 1, 0, 'x', { .all : 0 } }; }
     257        _Ostream_Manip(const char *) wd( unsigned char w, const char * v ) { return (_Ostream_Manip(const char *))@{ v, w, 0, 's', { .all : 0 } }; }
     258        _Ostream_Manip(const char *) wd( unsigned char w, unsigned char p, const char * v ) { return (_Ostream_Manip(const char *))@{ v, w, p, 's', { .flags.pc : true } }; }
     259        _Ostream_Manip(const char *) & wd( unsigned char w, _Ostream_Manip(const char *) & fmt ) with(fmt) { wd = w; return fmt; }
     260        _Ostream_Manip(const char *) & wd( unsigned char w, unsigned char p, _Ostream_Manip(const char *) & fmt ) with(fmt) { wd = w; pc = p; flags.pc = true; return fmt; }
     261        _Ostream_Manip(const char *) & left( _Ostream_Manip(const char *) & fmt ) { fmt.flags.left = true; return fmt; }
     262        _Ostream_Manip(const char *) & nobase( _Ostream_Manip(const char *) & fmt ) { fmt.flags.nobsdp = true; return fmt; }
     263} // distribution
     264forall( dtype ostype | ostream( ostype ) ) {
     265        ostype & ?|?( ostype & os, _Ostream_Manip(const char *) f );
     266        void ?|?( ostype & os, _Ostream_Manip(const char *) f );
     267}
     268
     269
     270//*********************************** Istream ***********************************
     271
    149272
    150273trait istream( dtype istype ) {
     
    204327forall( dtype istype | istream( istype ) ) istype & ?|?( istype &, _Istream_cstrC );
    205328
     329#if 0
     330struct _Istream_Cstr {
     331        char * s, * scanset;
     332        int wd;                                                                                         // width
     333        bool ignore;                                                                            // no input argument
     334};
     335static inline _Istream_Cstr skip( char * s ) { return (_Istream_Cstr){ 0p, s, -1, false }; }
     336static inline _Istream_Cstr incl( const char * scanset, char * s ) { return (_Istream_Cstr){ s, scanset, -1, false }; }
     337static inline _Istream_Cstr excl( const char * scanset, char * s ) { return (_Istream_Cstr){ s, scanset, -1, false }; }
     338static inline _Istream_Cstr cstr( char * s ) { return (_Istream_Cstr){ s, 0p, -1, false }; }
     339static inline _Istream_Cstr ignore( char * s ) { return (_Istream_Cstr)@{ s, 0p, -1, true }; }
     340static inline _Istream_Cstr ignore( _Istream_Cstr & fmt ) { fmt.ignore = true; return fmt; }
     341static inline _Istream_Cstr wd( unsigned int w, char * s ) { return (_Istream_Cstr)@{ s, 0p, w, false }; }
     342forall( dtype istype | istream( istype ) ) istype & ?|?( istype &, _Istream_Cstr );
     343
     344//*********************************** Manipulators ***********************************
     345
     346forall( otype T )
     347struct _Istream_Manip {
     348        T & val;                                                                                        // polymorphic base-type
     349        int wd;                                                                                         // width
     350        bool ignore;                                                                            // no input argument
     351}; // _Istream_Manip
     352
     353#define InputFMTDecl( T ) \
     354static inline _Istream_Manip(T) ignore( T & v ) { return (_Istream_Manip(T))@{ v, -1, true }; } \
     355static inline _Istream_Manip(T) ignore( _Istream_Manip(T) & fmt ) { fmt.ignore = true; return fmt; } \
     356static inline _Istream_Manip(T) wd( unsigned int w, T & v ) { return (_Istream_Manip(T))@{ v, w, false }; } \
     357forall( dtype istype | istream( istype ) ) { \
     358        istype & ?|?( istype & is, _Istream_Manip(T) f ); \
     359}
     360
     361InputFMTDecl( char )
     362InputFMTDecl( signed char )
     363InputFMTDecl( unsigned char )
     364InputFMTDecl( signed short int )
     365InputFMTDecl( unsigned short int )
     366InputFMTDecl( signed int )
     367InputFMTDecl( unsigned int )
     368InputFMTDecl( signed long int )
     369InputFMTDecl( unsigned long int )
     370InputFMTDecl( signed long long int )
     371InputFMTDecl( unsigned long long int )
     372
     373InputFMTDecl( float )
     374InputFMTDecl( double )
     375InputFMTDecl( long double )
     376
     377InputFMTDecl( float _Complex )
     378InputFMTDecl( double _Complex )
     379InputFMTDecl( long double _Complex )
     380#endif // 0
     381
     382
     383//*********************************** Time ***********************************
     384
    206385
    207386#include <time_t.hfa>                                                                   // Duration (constructors) / Time (constructors)
Note: See TracChangeset for help on using the changeset viewer.