Ignore:
Timestamp:
Aug 11, 2020, 4:40:15 PM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
0d070ca
Parents:
07d867b (diff), 129674b (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' into new-ast

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/iostream.cfa

    r07d867b r22f94a4  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat May  2 18:30:25 2020
    13 // Update Count     : 1017
     12// Last Modified On : Mon Aug 10 09:32:14 2020
     13// Update Count     : 1126
    1414//
    1515
    1616#include "iostream.hfa"
    1717
    18 extern "C" {
    1918#include <stdio.h>
    2019#include <stdbool.h>                                                                    // true/false
    2120#include <stdint.h>                                                                             // UINT64_MAX
     21#include <float.h>                                                                              // DBL_DIG, LDBL_DIG
     22#include <math.h>                                                                               // isfinite
     23#include <complex.h>                                                                    // creal, cimag
    2224//#include <string.h>                                                                   // strlen, strcmp
     25extern "C" {
    2326extern size_t strlen (const char *__s) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1)));
    2427extern int strcmp (const char *__s1, const char *__s2) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2)));
    2528extern char *strcpy (char *__restrict __dest, const char *__restrict __src) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
    2629extern void *memcpy (void *__restrict __dest, const void *__restrict __src, size_t __n) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
    27 #include <float.h>                                                                              // DBL_DIG, LDBL_DIG
    28 #include <math.h>                                                                               // isfinite
    29 #include <complex.h>                                                                    // creal, cimag
    3030} // extern "C"
    3131
    32 #include <bitmanip.hfa>                                                                 // fms
    33 
    34 
    35 //*********************************** ostream ***********************************
     32#include <bitmanip.hfa>                                                                 // high1
     33
     34
     35// *********************************** ostream ***********************************
    3636
    3737
     
    167167        #define P10_UINT64 10_000_000_000_000_000_000_ULL       // 19 zeroes
    168168
    169         static void base10_128( ostype & os, unsigned int128 val ) {
    170                 if ( val > UINT64_MAX ) {
     169        static inline void base10_128( ostype & os, unsigned int128 val ) {
     170#if defined(__GNUC__) && __GNUC_PREREQ(7,0)                             // gcc version >= 7
     171                if ( val > P10_UINT64 ) {
     172#else
     173                if ( (uint64_t)(val >> 64) != 0 || (uint64_t)val > P10_UINT64 ) { // patch gcc 5 & 6 -O3 bug
     174#endif // __GNUC_PREREQ(7,0)
    171175                        base10_128( os, val / P10_UINT64 );                     // recursive
    172176                        fmt( os, "%.19lu", (uint64_t)(val % P10_UINT64) );
     
    176180        } // base10_128
    177181
    178         static void base10_128( ostype & os, int128 val ) {
     182        static inline void base10_128( ostype & os, int128 val ) {
    179183                if ( val < 0 ) {
    180184                        fmt( os, "-" );                                                         // leading negative sign
     
    447451} // distribution
    448452
    449 //*********************************** manipulators ***********************************
    450 
    451 //*********************************** integral ***********************************
     453// *********************************** manipulators ***********************************
     454
     455// *********************************** integral ***********************************
    452456
    453457static const char * shortbin[] = { "0", "1", "10", "11", "100", "101", "110", "111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111" };
     
    455459
    456460// Default prefix for non-decimal prints is 0b, 0, 0x.
    457 #define IntegralFMTImpl( T, CODE, IFMTNP, IFMTP ) \
     461#define IntegralFMTImpl( T, IFMTNP, IFMTP ) \
    458462forall( dtype ostype | ostream( ostype ) ) { \
    459463        ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \
     
    506510                        if ( f.flags.left && spaces > 0 ) fmt( os, "%*s", spaces, " " ); \
    507511                        return os; \
    508                 } /* if  */ \
     512                } /* if */ \
    509513\
    510514                char fmtstr[sizeof(IFMTP)];                                             /* sizeof includes '\0' */ \
     
    516520                if ( ! f.flags.nobsdp ) { fmtstr[star] = '#'; star -= 1; } \
    517521                if ( f.flags.left ) { fmtstr[star] = '-'; star -= 1; } \
    518                 if ( f.flags.sign && f.base == CODE ) { fmtstr[star] = '+'; star -= 1; } \
     522                if ( f.flags.sign ) { fmtstr[star] = '+'; star -= 1; } \
    519523                if ( f.flags.pad0 && ! f.flags.pc ) { fmtstr[star] = '0'; star -= 1; } \
    520524                fmtstr[star] = '%'; \
     
    522526                if ( ! f.flags.pc ) {                                                   /* no precision */ \
    523527                        fmtstr[sizeof(IFMTNP)-2] = f.base;                      /* sizeof includes '\0' */ \
    524                         /* printf( "%s %c %c\n", &fmtstr[star], f.base, CODE ); */ \
     528                        /* printf( "%s %c\n", &fmtstr[star], f.base ); */ \
    525529                        fmt( os, &fmtstr[star], f.wd, f.val ); \
    526530                } else {                                                                                /* precision */ \
    527531                        fmtstr[sizeof(IFMTP)-2] = f.base;                       /* sizeof includes '\0' */ \
    528                         /* printf( "%s %c %c\n", &fmtstr[star], f.base, CODE ); */ \
     532                        /* printf( "%s %c\n", &fmtstr[star], f.base ); */ \
    529533                        fmt( os, &fmtstr[star], f.wd, f.pc, f.val ); \
    530534                } /* if */ \
     
    534538} // distribution
    535539
    536 IntegralFMTImpl( signed char, 'd', "%    *hh ", "%    *.*hh " )
    537 IntegralFMTImpl( unsigned char, 'u', "%    *hh ", "%    *.*hh " )
    538 IntegralFMTImpl( signed short int, 'd', "%    *h ", "%    *.*h " )
    539 IntegralFMTImpl( unsigned short int, 'u', "%    *h ", "%    *.*h " )
    540 IntegralFMTImpl( signed int, 'd', "%    * ", "%    *.* " )
    541 IntegralFMTImpl( unsigned int, 'u', "%    * ", "%    *.* " )
    542 IntegralFMTImpl( signed long int, 'd', "%    *l ", "%    *.*l " )
    543 IntegralFMTImpl( unsigned long int, 'u', "%    *l ", "%    *.*l " )
    544 IntegralFMTImpl( signed long long int, 'd', "%    *ll ", "%    *.*ll " )
    545 IntegralFMTImpl( unsigned long long int, 'u', "%    *ll ", "%    *.*ll " )
    546 
    547 
     540IntegralFMTImpl( signed char, "%    *hh ", "%    *.*hh " )
     541IntegralFMTImpl( unsigned char, "%    *hh ", "%    *.*hh " )
     542IntegralFMTImpl( signed short int, "%    *h ", "%    *.*h " )
     543IntegralFMTImpl( unsigned short int, "%    *h ", "%    *.*h " )
     544IntegralFMTImpl( signed int, "%    * ", "%    *.* " )
     545IntegralFMTImpl( unsigned int, "%    * ", "%    *.* " )
     546IntegralFMTImpl( signed long int, "%    *l ", "%    *.*l " )
     547IntegralFMTImpl( unsigned long int, "%    *l ", "%    *.*l " )
     548IntegralFMTImpl( signed long long int, "%    *ll ", "%    *.*ll " )
     549IntegralFMTImpl( unsigned long long int, "%    *ll ", "%    *.*ll " )
     550
     551#if 0
    548552#if defined( __SIZEOF_INT128__ )
    549553// Default prefix for non-decimal prints is 0b, 0, 0x.
     
    611615                                                sepOff( os ); \
    612616                                                fmt2.flags.left = true; \
    613                                                 int msigd = ceiling( high1( fmt.val ), 3 ); \
     617                                                int msigd = ceiling_div( high1( fmt.val ), 3 ); \
    614618                                                fmt2.wd = f.wd - (fmt.pc > msigd ? fmt.pc : msigd); \
    615619                                                if ( ! fmt.flags.nobsdp ) fmt2.wd -= 1; /* compensate for 0 base specifier */ \
     
    663667IntegralFMTImpl128( unsigned int128, unsigned, 'u', "%    *ll ", "%    *.*ll " )
    664668#endif // __SIZEOF_INT128__
    665 
    666 //*********************************** floating point ***********************************
     669#endif // 0
     670
     671#if 1
     672#if defined( __SIZEOF_INT128__ )
     673// Default prefix for non-decimal prints is 0b, 0, 0x.
     674forall( dtype ostype | ostream( ostype ) )
     675static 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 ) {
     676        int wd = 1;                                                                                     // f.wd is never 0 because 0 implies left-pad
     677        if ( val > power ) {                                                            // subdivide value into printable 64-bit values
     678                base_128( os, val / power, power, f, maxdig, bits, cnt + 1 ); // recursive
     679                f.val = val % power;
     680                if ( cnt == 1 && f.flags.left ) { wd = f.wd; f.wd = maxdig; } // copy f.wd and reset for printing middle chunk
     681                // printf( "R val:%#lx(%lu) wd:%u pc:%u base:%c neg:%d pc:%d left:%d nobsdp:%d sign:%d pad0:%d\n",
     682                //              f.val, f.val, f.wd, f.pc, f.base, f.flags.neg, f.flags.pc, f.flags.left, f.flags.nobsdp, f.flags.sign, f.flags.pad0 );
     683                (ostype &)(os | f);
     684                if ( cnt == 1 ) {
     685                        if ( f.flags.left ) { wd -= maxdig; f.wd = wd < 0 ? 1 : wd; } // update and restore f.wd for printing end chunk
     686                        sepOff( os );                                                           // no seperator between chunks
     687                } // if
     688        } else {                                                                                        // print start chunk
     689                f.val = val;
     690                // f.pc is unsigned => use wd
     691                if ( f.flags.pc && f.pc > maxdig * cnt ) { wd = f.pc - maxdig * cnt; f.pc = wd < 0 ? 0 : wd; }
     692                else { f.flags.pc = false; f.pc = 0; }
     693
     694                if ( ! f.flags.left ) {                                                 // right justify
     695                        wd = f.wd - maxdig * cnt;
     696                        f.wd = wd < 0 ? 1 : wd;
     697                        wd = maxdig;
     698                } else {                                                                                // left justify
     699                        if ( cnt != 0 ) {                                                       // value >= 2^64 ?
     700                                unsigned int dig, bs = 0;
     701                                // compute size of prefix digits and base
     702                                if ( f.base == 'd' || f.base == 'u' ) { // no base prefix
     703                                        dig = ceil( log10( f.val ) );           // use floating-point
     704                                        if ( f.base == 'd' && (f.flags.neg || f.flags.sign) ) bs = 1; // sign ?
     705                                } else {
     706                                        dig = ceiling_div( high1( f.val ), bits );
     707                                        if ( ! f.flags.nobsdp ) {                       // base prefix ?
     708                                                if ( f.base == 'o' ) {
     709                                                        // 0 prefix for octal is not added for precision with leading zero
     710                                                        if ( f.pc <= dig ) bs = 1;      // 1 character prefix
     711                                                } else bs = 2;                                  // 2 character prefix
     712                                        } // if
     713                                } // if
     714                                wd = f.wd - (f.pc > dig ? f.pc : dig) - bs; // precision > leading digits ?
     715                                if ( wd < 0 ) wd = 1;
     716                                f.wd = 1;
     717                        } // if
     718                        // all manipulators handled implicitly for value < 2^64
     719                } // if
     720                // prior checks ensure wd not negative
     721
     722                if ( f.flags.neg ) f.val = -f.val;
     723                // printf( "L val:%#lx(%lu) wd:%u pc:%u base:%c neg:%d pc:%d left:%d nobsdp:%d sign:%d pad0:%d\n",
     724                //              f.val, f.val, f.wd, f.pc, f.base, f.flags.neg, f.flags.pc, f.flags.left, f.flags.nobsdp, f.flags.sign, f.flags.pad0 );
     725                (ostype &)(os | f);
     726
     727                // remaining middle and end chunks are padded with 0s on the left
     728                if ( ! f.flags.left ) { f.flags.pad0 = true; f.flags.pc = false; } // left pad with 0s
     729                else { f.pc = maxdig; f.flags.pc = true; }              // left pad with precision
     730
     731                if ( cnt != 0 ) sepOff( os );                                   // no seperator between chunks
     732                f.wd = wd;                                                                              // reset f.wd for next chunk
     733                f.flags.sign = false;                                                   // no leading +/- sign
     734                f.flags.nobsdp = true;                                                  // no leading base prefix
     735        } // if
     736} // base_128
     737
     738#define IntegralFMTImpl128( T ) \
     739forall( dtype ostype | ostream( ostype ) ) { \
     740        ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \
     741                _Ostream_Manip(uint64_t) fmt; \
     742                fmt.[wd, pc, base, all] = f.[wd, pc, base, all]; \
     743                if ( f.base == 'b' | f.base == 'B' ) { \
     744                        base_128( os, f.val, (unsigned int128)1 << 64, fmt, 64, 1 ); \
     745                } else if ( f.base == 'o' ) { \
     746                        base_128( os, f.val, (unsigned int128)1 << 63, fmt, 21, 3 ); \
     747                } else if ( f.base == 'd' || f.base == 'u' ) { \
     748                        if ( f.base == 'd' && f.val < 0 ) { f.val = -f.val; fmt.flags.neg = true; } \
     749                        base_128( os, f.val, (unsigned int128)10_000_000_000_000_000_000UL, fmt, 19, 0 ); \
     750                } else { \
     751                        base_128( os, f.val, (unsigned int128)1 << 64, fmt, 16, 4 ); \
     752                } /* if */ \
     753                return os; \
     754        } /* ?|? */ \
     755        void ?|?( ostype & os, _Ostream_Manip(T) f ) { (ostype &)(os | f); ends( os ); } \
     756} // distribution
     757
     758IntegralFMTImpl128( int128 )
     759IntegralFMTImpl128( unsigned int128 )
     760#endif // __SIZEOF_INT128__
     761#endif // 0
     762
     763// *********************************** floating point ***********************************
    667764
    668765#define PrintWithDP2( os, format, val, ... ) \
     
    720817FloatingPointFMTImpl( long double, "%    *L ", "%    *.*L " )
    721818
    722 //*********************************** character ***********************************
     819// *********************************** character ***********************************
    723820
    724821forall( dtype ostype | ostream( ostype ) ) {
     
    753850} // distribution
    754851
    755 //*********************************** C string ***********************************
     852// *********************************** C string ***********************************
    756853
    757854forall( dtype ostype | ostream( ostype ) ) {
     
    800897
    801898
    802 //*********************************** istream ***********************************
     899// *********************************** istream ***********************************
    803900
    804901
     
    877974        } // ?|?
    878975
     976#if defined( __SIZEOF_INT128__ )
     977        istype & ?|?( istype & is, int128 & i128 ) {
     978                return (istype &)(is | (unsigned int128 &)i128);
     979        } // ?|?
     980
     981        istype & ?|?( istype & is, unsigned int128 & ui128 ) {
     982                char s[40];
     983                bool sign = false;
     984
     985                if ( fmt( is, " %[-]", s ) == 1 ) sign = true;  // skip whitespace, negative sign ?
     986                // If the input is too large, the value returned is undefined. If there is no input, no value is returned
     987                if ( fmt( is, "%39[0-9]%*[0-9]", s ) == 1 ) {   // take first 39 characters, ignore remaining
     988                        ui128 = 0;
     989                        for ( unsigned int i = 0; s[i] != '\0'; i += 1 ) {
     990                                ui128 = ui128 * 10 + s[i] - '0';
     991                        } // for
     992                        if ( sign ) ui128 = -ui128;
     993                } else if ( sign ) ungetc( is, '-' );                   // return minus when no digits
     994                return is;
     995        } // ?|?
     996#endif // __SIZEOF_INT128__
    879997
    880998        istype & ?|?( istype & is, float & f ) {
     
    9461064} // distribution
    9471065
    948 //*********************************** manipulators ***********************************
     1066// *********************************** manipulators ***********************************
    9491067
    9501068forall( dtype istype | istream( istype ) )
Note: See TracChangeset for help on using the changeset viewer.