Changeset e7f8119 for libcfa/src


Ignore:
Timestamp:
Jun 10, 2019, 10:52:03 AM (6 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
6355ba7
Parents:
9856ca9 (diff), 61c7239 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
libcfa/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/iostream.cfa

    r9856ca9 re7f8119  
    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 : Sun Jun  9 16:27:17 2019
     13// Update Count     : 803
    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"
     30
     31
     32//*********************************** Ostream ***********************************
     33
    2834
    2935forall( dtype ostype | ostream( ostype ) ) {
     
    198204                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    199205//              os | crealf( fc ) | nonl;
    200                 float f = crealf( fc );
    201                 PrintWithDP( os, "%g", f );
    202                 f = cimagf( fc );
    203                 PrintWithDP( os, "%+g", f );
     206                PrintWithDP( os, "%g", crealf( fc ) );
     207                PrintWithDP( os, "%+g", cimagf( fc ) );
    204208                fmt( os, "i" );
    205209                return os;
     
    212216                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    213217//              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 );
     218                PrintWithDP( os, "%.*lg", creal( dc ), DBL_DIG );
     219                PrintWithDP( os, "%+.*lg", cimag( dc ), DBL_DIG );
    218220                fmt( os, "i" );
    219221                return os;
     
    226228                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    227229//              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 );
     230                PrintWithDP( os, "%.*Lg", creall( ldc ), LDBL_DIG );
     231                PrintWithDP( os, "%+.*Lg", cimagl( ldc ), LDBL_DIG );
    232232                fmt( os, "i" );
    233233                return os;
     
    395395} // distribution
    396396
    397 //---------------------------------------
    398 
    399397// writes the range [begin, end) to the given stream
    400398forall( dtype ostype, otype elt_type | writeable( elt_type, ostype ), otype iterator_type | iterator( iterator_type, elt_type ) ) {
     
    410408} // distribution
    411409
    412 //---------------------------------------
     410//*********************************** Manipulators ***********************************
     411
     412//*********************************** Integral ***********************************
     413
     414static const char * shortbin[] = { "0", "1", "10", "11", "100", "101", "110", "111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111" };
     415static const char * longbin[]  = { "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111" };
     416
     417// Default prefix for non-decimal prints is 0b, 0, 0x.
     418#define IntegralFMTImpl( T, CODE, IFMTNP, IFMTP ) \
     419forall( dtype ostype | ostream( ostype ) ) { \
     420        ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \
     421                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) ); \
     422\
     423                if ( f.base == 'b' || f.base == 'B' ) {                 /* bespoke binary format */ \
     424                        int bits;                                                                                                       \
     425                        if ( f.val == (T){0} ) bits = 1;                        /* force at least one bit to print */ \
     426                        else bits = sizeof(long long int) * 8 - __builtin_clzll( f.val ); /* position of most significant bit */ \
     427                        bits = bits > sizeof(f.val) * 8 ? sizeof(f.val) * 8 : bits; \
     428                        int spaces = f.wd - bits;                                       /* can be negative */ \
     429                        if ( ! f.flags.nobsdp ) { spaces -= 2; }        /* base prefix takes space */ \
     430                        /* printf( "%d %d\n", bits, spaces ); */ \
     431                        if ( ! f.flags.left ) {                                         /* right justified ? */ \
     432                                /* Note, base prefix then zero padding or spacing then prefix. */ \
     433                                if ( f.flags.pad0 || f.flags.pc ) { \
     434                                        if ( ! f.flags.nobsdp ) { fmt( os, "0%c", f.base ); } \
     435                                        if ( f.flags.pc ) spaces = f.pc - bits; \
     436                                        if ( spaces > 0 ) fmt( os, "%0*d", spaces, 0 ); /* zero pad */ \
     437                                } else { \
     438                                        if ( spaces > 0 ) fmt( os, "%*s", spaces, " " ); /* space pad */ \
     439                                        if ( ! f.flags.nobsdp ) { fmt( os, "0%c", f.base ); } \
     440                                } /* if */ \
     441                        } else if ( ! f.flags.nobsdp ) { \
     442                                fmt( os, "0%c", f.base ); \
     443                        } /* if */ \
     444                        int shift = (bits - 1) / 4 * 4; /* floor( bits - 1, 4 ) */ \
     445                        typeof( f.val ) temp = f.val; \
     446                        fmt( os, "%s", shortbin[(temp >> shift) & 0xf] ); \
     447                        for () { \
     448                                shift -= 4; \
     449                          if ( shift < 0 ) break; \
     450                                temp = f.val; \
     451                                fmt( os, "%s", longbin[(temp >> shift) & 0xf] ); \
     452                        } /* for */ \
     453                        if ( f.flags.left && spaces > 0 ) fmt( os, "%*s", spaces, " " ); \
     454                        return os; \
     455                } /* if  */ \
     456\
     457                char fmtstr[sizeof(IFMTP)];                                             /* sizeof includes '\0' */ \
     458                if ( ! f.flags.pc ) memcpy( &fmtstr, IFMTNP, sizeof(IFMTNP) ); \
     459                else memcpy( &fmtstr, IFMTP, sizeof(IFMTP) ); \
     460                int star = 4;                                                                   /* position before first '*' */ \
     461\
     462                /* Insert flags into spaces before '*', from right to left. */ \
     463                if ( ! f.flags.nobsdp ) { fmtstr[star] = '#'; star -= 1; } \
     464                if ( f.flags.left ) { fmtstr[star] = '-'; star -= 1; } \
     465                if ( f.flags.sign && f.base == CODE ) { fmtstr[star] = '+'; star -= 1; } \
     466                if ( f.flags.pad0 && ! f.flags.pc ) { fmtstr[star] = '0'; star -= 1; } \
     467                fmtstr[star] = '%'; \
     468\
     469                if ( ! f.flags.pc ) {                                                   /* no precision */ \
     470                        /* printf( "%s\n", &fmtstr[star] ); */ \
     471                        fmtstr[sizeof(IFMTNP)-2] = f.base;                      /* sizeof includes '\0' */ \
     472                        fmt( os, &fmtstr[star], f.wd, f.val ); \
     473                } else {                                                                                /* precision */ \
     474                        fmtstr[sizeof(IFMTP)-2] = f.base;                       /* sizeof includes '\0' */ \
     475                        /* printf( "%s\n", &fmtstr[star] ); */ \
     476                        fmt( os, &fmtstr[star], f.wd, f.pc, f.val ); \
     477                } /* if */ \
     478                return os; \
     479        } /* ?|? */ \
     480        void ?|?( ostype & os, _Ostream_Manip(T) f ) { (ostype &)(os | f); nl( os ); } \
     481} // distribution
     482
     483IntegralFMTImpl( signed char, 'd', "%    *hh ", "%    *.*hh " )
     484IntegralFMTImpl( unsigned char, 'u', "%    *hh ", "%    *.*hh " )
     485IntegralFMTImpl( signed short int, 'd', "%    *h ", "%    *.*h " )
     486IntegralFMTImpl( unsigned short int, 'u', "%    *h ", "%    *.*h " )
     487IntegralFMTImpl( signed int, 'd', "%    * ", "%    *.* " )
     488IntegralFMTImpl( unsigned int, 'u', "%    * ", "%    *.* " )
     489IntegralFMTImpl( signed long int, 'd', "%    *l ", "%    *.*l " )
     490IntegralFMTImpl( unsigned long int, 'u', "%    *l ", "%    *.*l " )
     491IntegralFMTImpl( signed long long int, 'd', "%    *ll ", "%    *.*ll " )
     492IntegralFMTImpl( unsigned long long int, 'u', "%    *ll ", "%    *.*ll " )
     493
     494//*********************************** Floating Point ***********************************
     495
     496#define PrintWithDP2( os, format, val, ... ) \
     497        { \
     498                enum { size = 48 }; \
     499                char buf[size]; \
     500                int bufbeg = 0, i, len = snprintf( buf, size, format, ##__VA_ARGS__, val ); \
     501                if ( isfinite( val ) && (f.base != 'g' || f.pc != 0) ) { /* if number, print decimal point */ \
     502                        for ( i = 0; i < len && buf[i] != '.' && buf[i] != 'e' && buf[i] != 'E'; i += 1 ); /* decimal point or scientific ? */ \
     503                        if ( i == len && ! f.flags.nobsdp ) { \
     504                                if ( ! f.flags.left ) { \
     505                                        buf[i] = '.'; buf[i + 1] = '\0'; \
     506                                        if ( buf[0] == ' ' ) bufbeg = 1; /* decimal point within width */ \
     507                                } else { \
     508                                        for ( i = 0; i < len && buf[i] != ' '; i += 1 ); /* trailing blank ? */ \
     509                                        buf[i] = '.'; \
     510                                        if ( i == len ) buf[i + 1] = '\0'; \
     511                                } /* if */ \
     512                        } /* if */ \
     513                } /* if */ \
     514                fmt( os, "%s", &buf[bufbeg] ); \
     515        }
     516
     517#define FloatingPointFMTImpl( T, DFMTNP, DFMTP ) \
     518forall( dtype ostype | ostream( ostype ) ) { \
     519        ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \
     520                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) ); \
     521                char fmtstr[sizeof(DFMTP)];                                             /* sizeof includes '\0' */ \
     522                if ( ! f.flags.pc ) memcpy( &fmtstr, DFMTNP, sizeof(DFMTNP) ); \
     523                else memcpy( &fmtstr, DFMTP, sizeof(DFMTP) ); \
     524                int star = 4;                                                                   /* position before first '*' */ \
     525\
     526                /* Insert flags into spaces before '*', from right to left. */ \
     527                if ( f.flags.left ) { fmtstr[star] = '-'; star -= 1; } \
     528                if ( f.flags.sign ) { fmtstr[star] = '+'; star -= 1; } \
     529                if ( f.flags.pad0 ) { fmtstr[star] = '0'; star -= 1; } \
     530                fmtstr[star] = '%'; \
     531\
     532                if ( ! f.flags.pc ) {                                                   /* no precision */ \
     533                        fmtstr[sizeof(DFMTNP)-2] = f.base;                      /* sizeof includes '\0' */ \
     534                        /* printf( "%g %d %s\n", f.val, f.wd, &fmtstr[star]); */ \
     535                        PrintWithDP2( os, &fmtstr[star], f.val, f.wd ) \
     536                } else {                                                                                /* precision */ \
     537                        fmtstr[sizeof(DFMTP)-2] = f.base;                       /* sizeof includes '\0' */ \
     538                        /* printf( "%g %d %d %s\n", f.val, f.wd, f.pc, &fmtstr[star] ); */ \
     539                        PrintWithDP2( os, &fmtstr[star], f.val, f.wd, f.pc ) \
     540                } /* if */ \
     541                return os; \
     542        } /* ?|? */ \
     543        void ?|?( ostype & os, _Ostream_Manip(T) f ) { (ostype &)(os | f); nl( os ); } \
     544} // distribution
     545
     546FloatingPointFMTImpl( double, "%    * ", "%    *.* " )
     547FloatingPointFMTImpl( long double, "%    *L ", "%    *.*L " )
     548
     549//*********************************** Character ***********************************
     550
     551forall( dtype ostype | ostream( ostype ) ) {
     552        ostype & ?|?( ostype & os, _Ostream_Manip(char) f ) {
     553                if ( f.base != 'c' ) {                                                          // bespoke binary/octal/hex format
     554                        _Ostream_Manip(unsigned char) fmtuc @= { f.val, f.wd, f.pc, f.base, {'\0'} };
     555                        fmtuc.flags.pc = f.flags.pc;
     556                        fmtuc.flags.nobsdp = f.flags.nobsdp;
     557//                      os | fmtuc | nonl;
     558                        (ostype &)(os | fmtuc);
     559                        return os;
     560                } // if
     561
     562                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     563
     564                #define CFMTNP "% * "
     565                char fmtstr[sizeof(CFMTNP)];                                            // sizeof includes '\0'
     566                memcpy( &fmtstr, CFMTNP, sizeof(CFMTNP) );
     567                int star = 1;                                                                           // position before first '*'
     568
     569                // Insert flags into spaces before '*', from right to left.
     570                if ( f.flags.left ) { fmtstr[star] = '-'; star -= 1; }
     571                fmtstr[star] = '%';
     572
     573                fmtstr[sizeof(CFMTNP)-2] = f.base;                                      // sizeof includes '\0'
     574                // printf( "%d %s\n", f.wd, &fmtstr[star] );
     575                fmt( os, &fmtstr[star], f.wd, f.val );
     576                return os;
     577        } // ?|?
     578        void ?|?( ostype & os, _Ostream_Manip(char) f ) { (ostype &)(os | f); nl( os ); }
     579} // distribution
     580
     581//*********************************** C String ***********************************
     582
     583forall( dtype ostype | ostream( ostype ) ) {
     584        ostype & ?|?( ostype & os, _Ostream_Manip(const char *) f ) {
     585                if ( ! f.val ) return os;                                               // null pointer ?
     586
     587                if ( f.base != 's' ) {                                                  // bespoke binary/octal/hex format
     588                        _Ostream_Manip(unsigned char) fmtuc @= { 0, f.wd, f.pc, f.base, {'\0'} };
     589                        fmtuc.flags.pc = f.flags.pc;
     590                        fmtuc.flags.nobsdp = f.flags.nobsdp;
     591                        for ( unsigned int i = 0; f.val[i] != '\0'; i += 1 ) {
     592                                fmtuc.val = f.val[i];
     593//                              os | fmtuc | nonl;
     594                                (ostype &)(os | fmtuc);
     595                        } // for
     596                        return os;
     597                } // if
     598
     599                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     600
     601                #define SFMTNP "% * "
     602                #define SFMTP "% *.* "
     603                char fmtstr[sizeof(SFMTP)];                                             // sizeof includes '\0'
     604                if ( ! f.flags.pc ) memcpy( &fmtstr, SFMTNP, sizeof(SFMTNP) );
     605                else memcpy( &fmtstr, SFMTP, sizeof(SFMTP) );
     606                int star = 1;                                                                   // position before first '*'
     607
     608                // Insert flags into spaces before '*', from right to left.
     609                if ( f.flags.left ) { fmtstr[star] = '-'; star -= 1; }
     610                fmtstr[star] = '%';
     611
     612                if ( ! f.flags.pc ) {                                                   // no precision
     613                        // printf( "%d %s\n", f.wd, &fmtstr[star] );
     614                        fmtstr[sizeof(SFMTNP)-2] = f.base;                      // sizeof includes '\0'
     615                        fmt( os, &fmtstr[star], f.wd, f.val );
     616                } else {                                                                                // precision
     617                        fmtstr[sizeof(SFMTP)-2] = f.base;                       // sizeof includes '\0'
     618                        // printf( "%d %d %s\n", f.wd, f.pc, &fmtstr[star] );
     619                        fmt( os, &fmtstr[star], f.wd, f.pc, f.val );
     620                } // if
     621                return os;
     622        } // ?|?
     623        void ?|?( ostype & os, _Ostream_Manip(const char *) f ) { (ostype &)(os | f); nl( os ); }
     624} // distribution
     625
     626
     627//*********************************** Istream ***********************************
     628
    413629
    414630forall( dtype istype | istream( istype ) ) {
     
    437653
    438654        istype & ?|?( istype & is, signed char & sc ) {
    439                 fmt( is, "%hhd", &sc );
     655                fmt( is, "%hhi", &sc );
    440656                return is;
    441657        } // ?|?
    442658
    443659        istype & ?|?( istype & is, unsigned char & usc ) {
    444                 fmt( is, "%hhu", &usc );
     660                fmt( is, "%hhi", &usc );
    445661                return is;
    446662        } // ?|?
    447663
    448664        istype & ?|?( istype & is, short int & si ) {
    449                 fmt( is, "%hd", &si );
     665                fmt( is, "%hi", &si );
    450666                return is;
    451667        } // ?|?
    452668
    453669        istype & ?|?( istype & is, unsigned short int & usi ) {
    454                 fmt( is, "%hu", &usi );
     670                fmt( is, "%hi", &usi );
    455671                return is;
    456672        } // ?|?
    457673
    458674        istype & ?|?( istype & is, int & i ) {
    459                 fmt( is, "%d", &i );
     675                fmt( is, "%i", &i );
    460676                return is;
    461677        } // ?|?
    462678
    463679        istype & ?|?( istype & is, unsigned int & ui ) {
    464                 fmt( is, "%u", &ui );
     680                fmt( is, "%i", &ui );
    465681                return is;
    466682        } // ?|?
    467683
    468684        istype & ?|?( istype & is, long int & li ) {
    469                 fmt( is, "%ld", &li );
     685                fmt( is, "%li", &li );
    470686                return is;
    471687        } // ?|?
    472688
    473689        istype & ?|?( istype & is, unsigned long int & ulli ) {
    474                 fmt( is, "%lu", &ulli );
     690                fmt( is, "%li", &ulli );
    475691                return is;
    476692        } // ?|?
    477693
    478694        istype & ?|?( istype & is, long long int & lli ) {
    479                 fmt( is, "%lld", &lli );
     695                fmt( is, "%lli", &lli );
    480696                return is;
    481697        } // ?|?
    482698
    483699        istype & ?|?( istype & is, unsigned long long int & ulli ) {
    484                 fmt( is, "%llu", &ulli );
     700                fmt( is, "%lli", &ulli );
    485701                return is;
    486702        } // ?|?
     
    505721        istype & ?|?( istype & is, float _Complex & fc ) {
    506722                float re, im;
    507                 fmt( is, "%g%gi", &re, &im );
     723                fmt( is, "%f%fi", &re, &im );
    508724                fc = re + im * _Complex_I;
    509725                return is;
     
    545761} // distribution
    546762
    547 _Istream_cstrUC cstr( char * str ) { return (_Istream_cstrUC){ str }; }
     763//*********************************** Manipulators ***********************************
     764
    548765forall( dtype istype | istream( istype ) )
    549 istype & ?|?( istype & is, _Istream_cstrUC cstr ) {
    550         fmt( is, "%s", cstr.s );
     766istype & ?|?( istype & is, _Istream_Cstr f ) {
     767        // skip xxx
     768        if ( ! f.s ) {
     769                // printf( "skip %s\n", f.scanset );
     770                fmt( is, f.scanset, "" );                                               // no input arguments
     771                return is;
     772        } // if
     773        size_t len = 0;
     774        if ( f.scanset ) len = strlen( f.scanset );
     775        char fmtstr[len + 16];
     776        int start = 1;
     777        fmtstr[0] = '%';
     778        if ( f.flags.ignore ) { fmtstr[1] = '*'; start += 1; }
     779        if ( f.wd != -1 ) { start += sprintf( &fmtstr[start], "%d", f.wd ); }
     780        // cstr %s, %*s, %ws, %*ws
     781        if ( ! f.scanset ) {
     782                fmtstr[start] = 's'; fmtstr[start + 1] = '\0';
     783                // printf( "cstr %s\n", fmtstr );
     784                fmt( is, fmtstr, f.s );
     785                return is;
     786        } // if
     787        // incl %[xxx],  %*[xxx],  %w[xxx],  %*w[xxx]
     788        // excl %[^xxx], %*[^xxx], %w[^xxx], %*w[^xxx]
     789        fmtstr[start] = '['; start += 1;
     790        if ( f.flags.inex ) { fmtstr[start] = '^'; start += 1; }
     791        strcpy( &fmtstr[start], f.scanset );                            // copy includes '\0'
     792        len += start;
     793        fmtstr[len] = ']'; fmtstr[len + 1] = '\0';
     794        // printf( "incl/excl %s\n", fmtstr );
     795        fmt( is, fmtstr, f.s );
    551796        return is;
    552 } // cstr
    553 
    554 _Istream_cstrC cstr( char * str, int size ) { return (_Istream_cstrC){ str, size }; }
     797} // ?|?
     798
     799#define InputFMTImpl( T, CODE ) \
     800forall( dtype istype | istream( istype ) ) \
     801istype & ?|?( istype & is, _Istream_Manip(T) f ) { \
     802        enum { size = 16 }; \
     803        char fmtstr[size]; \
     804        if ( f.wd == -1 || strcmp( CODE, "c" ) == 0 ) { /* ignore width with "c" */     \
     805                snprintf( fmtstr, size, "%%%s%s", f.ignore ? "*" : "", CODE ); \
     806        } else { \
     807                snprintf( fmtstr, size, "%%%s%d%s", f.ignore ? "*" : "", f.wd, CODE ); \
     808        } /* if */ \
     809        /* printf( "%d %s %p\n", f.wd, fmtstr, &f.val ); */ \
     810        fmt( is, fmtstr, &f.val ); \
     811        return is; \
     812} // ?|?
     813
     814InputFMTImpl( char, "c" )
     815InputFMTImpl( signed char, "hhi" )
     816InputFMTImpl( unsigned char, "hhi" )
     817InputFMTImpl( signed short int, "hi" )
     818InputFMTImpl( unsigned short int, "hi" )
     819InputFMTImpl( signed int, "i" )
     820InputFMTImpl( unsigned int, "i" )
     821InputFMTImpl( signed long int, "li" )
     822InputFMTImpl( unsigned long int, "li" )
     823InputFMTImpl( signed long long int, "lli" )
     824InputFMTImpl( unsigned long long int, "lli" )
     825
     826InputFMTImpl( float, "f" )
     827InputFMTImpl( double, "lf" )
     828InputFMTImpl( long double, "Lf" )
     829
    555830forall( dtype istype | istream( istype ) )
    556 istype & ?|?( istype & is, _Istream_cstrC cstr ) {
    557         char buf[16];
    558         sprintf( buf, "%%%ds", cstr.size );
    559         fmt( is, buf, cstr.s );
     831istype & ?|?( istype & is, _Istream_Manip(float _Complex) fc ) {
     832        float re, im;
     833        _Istream_Manip(float) fmtuc @= { re, fc.wd, fc.ignore };
     834        is | fmtuc;
     835        &fmtuc.val = &im;
     836        is | fmtuc;
     837        if ( ! fc.ignore ) fc.val = re + im * _Complex_I;       // re/im are uninitialized for ignore
    560838        return is;
    561 } // cstr
     839} // ?|?
     840
     841forall( dtype istype | istream( istype ) )
     842istype & ?|?( istype & is, _Istream_Manip(double _Complex) dc ) {
     843        double re, im;
     844        _Istream_Manip(double) fmtuc @= { re, dc.wd, dc.ignore };
     845        is | fmtuc;
     846        &fmtuc.val = &im;
     847        is | fmtuc;
     848        if ( ! dc.ignore ) dc.val = re + im * _Complex_I;       // re/im are uninitialized for ignore
     849        return is;
     850} // ?|?
     851
     852forall( dtype istype | istream( istype ) )
     853istype & ?|?( istype & is, _Istream_Manip(long double _Complex) ldc ) {
     854        long double re, im;
     855        _Istream_Manip(long double) fmtuc @= { re, ldc.wd, ldc.ignore };
     856        is | fmtuc;
     857        &fmtuc.val = &im;
     858        is | fmtuc;
     859        if ( ! ldc.ignore ) ldc.val = re + im * _Complex_I;     // re/im are uninitialized for ignore
     860        return is;
     861} // ?|?
    562862
    563863// Local Variables: //
  • libcfa/src/iostream.hfa

    r9856ca9 re7f8119  
    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 : Sat Jun  8 17:28:44 2019
     13// Update Count     : 312
    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// See 6.7.9. 19) The initialization shall occur in initializer list order, each initializer provided for a particular
     174// subobject overriding any previously listed initializer for the same subobject; ***all subobjects that are not
     175// initialized explicitly shall be initialized implicitly the same as objects that have static storage duration.***
     176
     177#define IntegralFMTDecl( T, CODE ) \
     178static inline { \
     179        _Ostream_Manip(T) bin( T val ) { return (_Ostream_Manip(T))@{ val, 1, 0, 'b', { .all : 0 } }; } \
     180        _Ostream_Manip(T) oct( T val ) { return (_Ostream_Manip(T))@{ val, 1, 0, 'o', { .all : 0 } }; } \
     181        _Ostream_Manip(T) hex( T val ) { return (_Ostream_Manip(T))@{ val, 1, 0, 'x', { .all : 0 } }; } \
     182        _Ostream_Manip(T) wd( unsigned char w, T val ) { return (_Ostream_Manip(T))@{ val, w, 0, CODE, { .all : 0 } }; } \
     183        _Ostream_Manip(T) wd( unsigned char w, unsigned char pc, T val ) { return (_Ostream_Manip(T))@{ val, w, pc, CODE, { .flags.pc : true } }; } \
     184        _Ostream_Manip(T) & wd( unsigned char w, _Ostream_Manip(T) & fmt ) { fmt.wd = w; return fmt; } \
     185        _Ostream_Manip(T) & wd( unsigned char w, unsigned char pc, _Ostream_Manip(T) & fmt ) { fmt.wd = w; fmt.pc = pc; fmt.flags.pc = true; return fmt; } \
     186        _Ostream_Manip(T) & left( _Ostream_Manip(T) & fmt ) { fmt.flags.left = true; return fmt; } \
     187        _Ostream_Manip(T) & upcase( _Ostream_Manip(T) & fmt ) { if ( fmt.base == 'x' || fmt.base == 'b' ) fmt.base -= 32; /* upper case */ return fmt; } \
     188        _Ostream_Manip(T) & nobase( _Ostream_Manip(T) & fmt ) { fmt.flags.nobsdp = true; return fmt; } \
     189        _Ostream_Manip(T) & pad0( _Ostream_Manip(T) & fmt ) { fmt.flags.pad0 = true; return fmt; } \
     190        _Ostream_Manip(T) sign( T val ) { return (_Ostream_Manip(T))@{ val, 1, 0, CODE, { .flags.sign : true } }; } \
     191        _Ostream_Manip(T) & sign( _Ostream_Manip(T) & fmt ) { fmt.flags.sign = true; return fmt; } \
     192} \
     193forall( dtype ostype | ostream( ostype ) ) { \
     194        ostype & ?|?( ostype & os, _Ostream_Manip(T) f ); \
     195        void ?|?( ostype & os, _Ostream_Manip(T) f ); \
     196} // ?|?
     197
     198IntegralFMTDecl( signed char, 'd' )
     199IntegralFMTDecl( unsigned char, 'u' )
     200IntegralFMTDecl( signed short int, 'd' )
     201IntegralFMTDecl( unsigned short int, 'u' )
     202IntegralFMTDecl( signed int, 'd' )
     203IntegralFMTDecl( unsigned int, 'u' )
     204IntegralFMTDecl( signed long int, 'd' )
     205IntegralFMTDecl( unsigned long int, 'u' )
     206IntegralFMTDecl( signed long long int, 'd' )
     207IntegralFMTDecl( unsigned long long int, 'u' )
     208
     209//*********************************** Floating Point ***********************************
     210
     211// Default suffix for values with no fraction is "."
     212#define FloatingPointFMTDecl( T ) \
     213static inline { \
     214        _Ostream_Manip(T) hex( T val ) { return (_Ostream_Manip(T))@{ val, 1, 0, 'a', { .all : 0 } }; } \
     215        _Ostream_Manip(T) sci( T val ) { return (_Ostream_Manip(T))@{ val, 1, 0, 'e', { .all : 0 } }; } \
     216        _Ostream_Manip(T) wd( unsigned char w, T val ) { return (_Ostream_Manip(T))@{ val, w, 0, 'f', { .all : 0 } }; } \
     217        _Ostream_Manip(T) wd( unsigned char w, unsigned char pc, T val ) { return (_Ostream_Manip(T))@{ val, w, pc, 'f', { .flags.pc : true } }; } \
     218        _Ostream_Manip(T) ws( unsigned char w, unsigned char pc, T val ) { return (_Ostream_Manip(T))@{ val, w, pc, 'g', { .flags.pc : true } }; } \
     219        _Ostream_Manip(T) & wd( unsigned char w, _Ostream_Manip(T) & fmt ) { fmt.wd = w; return fmt; } \
     220        _Ostream_Manip(T) & wd( unsigned char w, unsigned char pc, _Ostream_Manip(T) & fmt ) { fmt.wd = w; fmt.pc = pc; fmt.flags.pc = true; return fmt; } \
     221        _Ostream_Manip(T) & left( _Ostream_Manip(T) & fmt ) { fmt.flags.left = true; return fmt; } \
     222        _Ostream_Manip(T) upcase( T val ) { return (_Ostream_Manip(T))@{ val, 1, 0, 'G', { .all : 0 } }; } \
     223        _Ostream_Manip(T) & upcase( _Ostream_Manip(T) & fmt ) { fmt.base -= 32; /* upper case */ return fmt; } \
     224        _Ostream_Manip(T) & pad0( _Ostream_Manip(T) & fmt ) { fmt.flags.pad0 = true; return fmt; } \
     225        _Ostream_Manip(T) sign( T val ) { return (_Ostream_Manip(T))@{ val, 1, 0, 'g', { .flags.sign : true } }; } \
     226        _Ostream_Manip(T) & sign( _Ostream_Manip(T) & fmt ) { fmt.flags.sign = true; return fmt; } \
     227        _Ostream_Manip(T) nodp( T val ) { return (_Ostream_Manip(T))@{ val, 1, 0, 'g', { .flags.nobsdp : true } }; } \
     228        _Ostream_Manip(T) & nodp( _Ostream_Manip(T) & fmt ) { fmt.flags.nobsdp = true; return fmt; } \
     229} \
     230forall( dtype ostype | ostream( ostype ) ) { \
     231        ostype & ?|?( ostype & os, _Ostream_Manip(T) f ); \
     232        void ?|?( ostype & os, _Ostream_Manip(T) f ); \
     233} // ?|?
     234
     235FloatingPointFMTDecl( double )
     236FloatingPointFMTDecl( long double )
     237
     238//*********************************** Character ***********************************
     239
     240static inline {
     241        _Ostream_Manip(char) bin( char val ) { return (_Ostream_Manip(char))@{ val, 1, 0, 'b', { .all : 0 } }; }
     242        _Ostream_Manip(char) oct( char val ) { return (_Ostream_Manip(char))@{ val, 1, 0, 'o', { .all : 0 } }; }
     243        _Ostream_Manip(char) hex( char val ) { return (_Ostream_Manip(char))@{ val, 1, 0, 'x', { .all : 0 } }; }
     244        _Ostream_Manip(char) wd( unsigned char w, char val ) { return (_Ostream_Manip(char))@{ val, w, 0, 'c', { .all : 0 } }; }
     245        _Ostream_Manip(char) & wd( unsigned char w, _Ostream_Manip(char) & fmt ) { fmt.wd = w; return fmt; }
     246        _Ostream_Manip(char) & left( _Ostream_Manip(char) & fmt ) { fmt.flags.left = true; return fmt; }
     247        _Ostream_Manip(char) & upcase( _Ostream_Manip(char) & fmt ) { if ( fmt.base == 'x' || fmt.base == 'b' ) fmt.base -= 32; /* upper case */ return fmt; }
     248        _Ostream_Manip(char) & nobase( _Ostream_Manip(char) & fmt ) { fmt.flags.nobsdp = true; return fmt; }
     249} // distribution
     250forall( dtype ostype | ostream( ostype ) ) {
     251        ostype & ?|?( ostype & os, _Ostream_Manip(char) f );
     252        void ?|?( ostype & os, _Ostream_Manip(char) f );
     253} // ?|?
     254
     255//*********************************** C String ***********************************
     256
     257static inline {
     258        _Ostream_Manip(const char *) bin( const char * val ) { return (_Ostream_Manip(const char *))@{ val, 1, 0, 'b', { .all : 0 } }; }
     259        _Ostream_Manip(const char *) oct( const char * val ) { return (_Ostream_Manip(const char *))@{ val, 1, 0, 'o', { .all : 0 } }; }
     260        _Ostream_Manip(const char *) hex( const char * val ) { return (_Ostream_Manip(const char *))@{ val, 1, 0, 'x', { .all : 0 } }; }
     261        _Ostream_Manip(const char *) wd( unsigned char w, const char * val ) { return (_Ostream_Manip(const char *))@{ val, w, 0, 's', { .all : 0 } }; }
     262        _Ostream_Manip(const char *) wd( unsigned char w, unsigned char pc, const char * val ) { return (_Ostream_Manip(const char *))@{ val, w, pc, 's', { .flags.pc : true } }; }
     263        _Ostream_Manip(const char *) & wd( unsigned char w, _Ostream_Manip(const char *) & fmt ) { fmt.wd = w; return fmt; }
     264        _Ostream_Manip(const char *) & wd( unsigned char w, unsigned char pc, _Ostream_Manip(const char *) & fmt ) { fmt.wd = w; fmt.pc = pc; fmt.flags.pc = true; return fmt; }
     265        _Ostream_Manip(const char *) & left( _Ostream_Manip(const char *) & fmt ) { fmt.flags.left = true; return fmt; }
     266        _Ostream_Manip(const char *) & nobase( _Ostream_Manip(const char *) & fmt ) { fmt.flags.nobsdp = true; return fmt; }
     267} // distribution
     268forall( dtype ostype | ostream( ostype ) ) {
     269        ostype & ?|?( ostype & os, _Ostream_Manip(const char *) f );
     270        void ?|?( ostype & os, _Ostream_Manip(const char *) f );
     271} // ?|?
     272
     273
     274//*********************************** Istream ***********************************
     275
    149276
    150277trait istream( dtype istype ) {
     
    189316        istype & ?|?( istype &, long double _Complex & );
    190317
     318        // Cannot have char & and char * => cstr manipulator
     319        // istype & ?|?( istype &, char * );
     320
    191321        // manipulators
    192322        istype & ?|?( istype &, istype & (*)( istype & ) );
     
    196326} // distribution
    197327
    198 struct _Istream_cstrUC { char * s; };
    199 _Istream_cstrUC cstr( char * );
    200 forall( dtype istype | istream( istype ) ) istype & ?|?( istype &, _Istream_cstrUC );
    201 
    202 struct _Istream_cstrC { char * s; int size; };
    203 _Istream_cstrC cstr( char *, int size );
    204 forall( dtype istype | istream( istype ) ) istype & ?|?( istype &, _Istream_cstrC );
     328//*********************************** Manipulators ***********************************
     329
     330struct _Istream_Cstr {
     331        char * s;
     332        const char * scanset;
     333        int wd;                                                                                         // width
     334        union {
     335                unsigned char all;
     336                struct {
     337                        unsigned char ignore:1;                                         // do not change input argument
     338                        unsigned char inex:1;                                           // include/exclude characters in scanset
     339                } flags;
     340        };
     341}; // _Istream_Cstr
     342
     343static inline _Istream_Cstr skip( const char * scanset ) { return (_Istream_Cstr){ 0p, scanset, -1, { .all : 0 } }; }
     344static inline _Istream_Cstr incl( const char * scanset, char * s ) { return (_Istream_Cstr){ s, scanset, -1, { .flags.inex : false } }; }
     345static inline _Istream_Cstr incl( const char * scanset, _Istream_Cstr & fmt ) { fmt.flags.inex = false; return fmt; }
     346static inline _Istream_Cstr excl( const char * scanset, char * s ) { return (_Istream_Cstr){ s, scanset, -1, { .flags.inex : true } }; }
     347static inline _Istream_Cstr excl( const char * scanset, _Istream_Cstr & fmt ) { fmt.flags.inex = true; return fmt; }
     348static inline _Istream_Cstr cstr( char * s ) { return (_Istream_Cstr){ s, 0p, -1, { .all : 0 } }; }
     349static inline _Istream_Cstr ignore( const char * s ) { return (_Istream_Cstr)@{ s, 0p, -1, { .flags.ignore : true } }; }
     350static inline _Istream_Cstr ignore( _Istream_Cstr & fmt ) { fmt.flags.ignore = true; return fmt; }
     351static inline _Istream_Cstr wd( unsigned int w, char * s ) { return (_Istream_Cstr)@{ s, 0p, w, { .all : 0 } }; }
     352static inline _Istream_Cstr wd( unsigned int w, _Istream_Cstr & fmt ) { fmt.wd = w; return fmt; }
     353forall( dtype istype | istream( istype ) ) istype & ?|?( istype &, _Istream_Cstr );
     354
     355forall( otype T )
     356struct _Istream_Manip {
     357        T & val;                                                                                        // polymorphic base-type
     358        int wd;                                                                                         // width
     359        bool ignore;                                                                            // do not change input argument
     360}; // _Istream_Manip
     361
     362#define InputFMTDecl( T ) \
     363static inline _Istream_Manip(T) ignore( const T & val ) { return (_Istream_Manip(T))@{ (T &)val, -1, true }; } \
     364static inline _Istream_Manip(T) ignore( _Istream_Manip(T) & fmt ) { fmt.ignore = true; return fmt; } \
     365static inline _Istream_Manip(T) wd( unsigned int w, T & val ) { return (_Istream_Manip(T))@{ val, w, false }; } \
     366forall( dtype istype | istream( istype ) ) { \
     367        istype & ?|?( istype & is, _Istream_Manip(T) f ); \
     368} // ?|?
     369
     370InputFMTDecl( char )
     371InputFMTDecl( signed char )
     372InputFMTDecl( unsigned char )
     373InputFMTDecl( signed short int )
     374InputFMTDecl( unsigned short int )
     375InputFMTDecl( signed int )
     376InputFMTDecl( unsigned int )
     377InputFMTDecl( signed long int )
     378InputFMTDecl( unsigned long int )
     379InputFMTDecl( signed long long int )
     380InputFMTDecl( unsigned long long int )
     381
     382InputFMTDecl( float )
     383InputFMTDecl( double )
     384InputFMTDecl( long double )
     385
     386InputFMTDecl( float _Complex )
     387InputFMTDecl( double _Complex )
     388InputFMTDecl( long double _Complex )
     389
     390
     391//*********************************** Time ***********************************
    205392
    206393
Note: See TracChangeset for help on using the changeset viewer.