// // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo // // The contents of this file are covered under the licence agreement in the // file "LICENCE" distributed with Cforall. // // stdlib.c -- // // Author : Peter A. Buhr // Created On : Thu Jan 28 17:10:29 2016 // Last Modified By : Peter A. Buhr // Last Modified On : Fri Mar 15 18:47:28 2024 // Update Count : 685 // #include "stdlib.hfa" #include "bits/random.hfa" #include "concurrency/invoke.h" // random_state //--------------------------------------- #include // memcpy, memset //#include // fabsf, fabs, fabsl #include // _Complex_I #include #include #pragma GCC visibility push(default) //--------------------------------------- // Cforall allocation/deallocation and constructor/destructor, array types forall( T & | sized(T), TT... | { void ?{}( T &, TT ); } ) T * anew( size_t dim, TT p ) { T * arr = alloc( dim ); for ( i; dim ) { (arr[i]){ p }; // run constructor } // for return arr; } // anew forall( T & | sized(T) | { void ^?{}( T & ); } ) void adelete( T arr[] ) { if ( arr ) { // ignore null size_t dim = malloc_size( arr ) / sizeof( T ); for ( i; 0 -~= dim - 1 ) { // reverse allocation order, must be unsigned ^(arr[i]){}; // run destructor } // for free( arr ); } // if } // adelete forall( T & | sized(T) | { void ^?{}( T & ); }, TT... | { void adelete( TT ); } ) void adelete( T arr[], TT rest ) { if ( arr ) { // ignore null size_t dim = malloc_size( arr ) / sizeof( T ); for ( i; 0 -~= dim - 1 ) { // reverse allocation order, must be unsigned ^(arr[i]){}; // run destructor } // for free( arr ); } // if adelete( rest ); } // adelete //--------------------------------------- // Cannot overload with singular (isspace) counterparts because they are macros. bool isalnums( const char s[] ) { for () { if ( *s == '\0' ) return true; if ( ! isalnum( *s ) ) return false; s += 1; } // for } // isalnums bool isalphas( const char s[] ) { for () { if ( *s == '\0' ) return true; if ( ! isalpha( *s ) ) return false; s += 1; } // for } // isblanks bool iscntrls( const char s[] ) { for () { if ( *s == '\0' ) return true; if ( ! iscntrl( *s ) ) return false; s += 1; } // for } // iscntrls bool isdigits( const char s[] ) { for () { if ( *s == '\0' ) return true; if ( ! isdigit( *s ) ) return false; s += 1; } // for } // isdigits bool isgraphs( const char s[] ) { for () { if ( *s == '\0' ) return true; if ( ! isgraph( *s ) ) return false; s += 1; } // for } // isgraphs bool islowers( const char s[] ) { for () { if ( *s == '\0' ) return true; if ( ! islower( *s ) ) return false; s += 1; } // for } // islowers bool isprints( const char s[] ) { for () { if ( *s == '\0' ) return true; if ( ! isprint( *s ) ) return false; s += 1; } // for } // isprints bool ispuncts( const char s[] ) { for () { if ( *s == '\0' ) return true; if ( ! ispunct( *s ) ) return false; s += 1; } // for } // ispuncts bool isspaces( const char s[] ) { for () { if ( *s == '\0' ) return true; if ( ! isspace( *s ) ) return false; s += 1; } // for } // isspaces bool isblanks( const char s[] ) { for () { if ( *s == '\0' ) return true; if ( ! isblank( *s ) ) return false; s += 1; } // for } // isblanks bool isuppers( const char s[] ) { for () { if ( *s == '\0' ) return true; if ( ! isupper( *s ) ) return false; s += 1; } // for } // isuppers bool isxdigits( const char s[] ) { for () { if ( *s == '\0' ) return true; if ( ! isxdigit( *s ) ) return false; s += 1; } // for } // isxdigits //--------------------------------------- float _Complex strto( const char sptr[], char * eptr[] ) { float re, im; char * eeptr; errno = 0; // reset re = strtof( sptr, &eeptr ); if ( sptr != eeptr ) { im = strtof( eeptr, &eeptr ); if ( sptr != eeptr ) { if ( *eeptr == 'i' ) { if ( eptr != 0p ) *eptr = eeptr + 1; return re + im * _Complex_I; } // if } // if } // if if ( eptr != 0p ) *eptr = eeptr; // error case return 0.0f + 0.0f * _Complex_I; } // strto double _Complex strto( const char sptr[], char * eptr[] ) { double re, im; char * eeptr; re = strtod( sptr, &eeptr ); if ( sptr != eeptr ) { im = strtod( eeptr, &eeptr ); if ( sptr != eeptr ) { if ( *eeptr == 'i' ) { if ( eptr != 0p ) *eptr = eeptr + 1; return re + im * _Complex_I; } // if } // if } // if if ( eptr != 0p ) *eptr = eeptr; // error case return 0.0 + 0.0 * _Complex_I; } // strto long double _Complex strto( const char sptr[], char * eptr[] ) { long double re, im; char * eeptr; re = strtold( sptr, &eeptr ); if ( sptr != eeptr ) { im = strtold( eeptr, &eeptr ); if ( sptr != eeptr ) { if ( *eeptr == 'i' ) { if ( eptr != 0p ) *eptr = eeptr + 1; return re + im * _Complex_I; } // if } // if } // if if ( eptr != 0p ) *eptr = eeptr; // error case return 0.0L + 0.0L * _Complex_I; } // strto forall( T | { T strto( const char sptr[], char * eptr[], int ); } ) T convert( const char sptr[] ) { // integral char * eptr; errno = 0; // reset T val = strto( sptr, &eptr, 10 ); // attempt conversion if ( errno == ERANGE ) throw ExceptionInst( out_of_range ); if ( eptr == sptr || // conversion failed, no characters generated eptr[0] != '\0' && ! isspaces( eptr ) ) throw ExceptionInst( invalid_argument ); // not at end of blank str ? return val; } // convert forall( T | { T strto( const char sptr[], char * eptr[] ); } ) T convert( const char sptr[] ) { // floating-point char * eptr; errno = 0; // reset T val = strto( sptr, &eptr ); // attempt conversion if ( errno == ERANGE ) throw ExceptionInst( out_of_range ); if ( eptr == sptr || // conversion failed, no characters generated eptr[0] != '\0' && ! isspaces( eptr ) ) throw ExceptionInst( invalid_argument ); // not at end of blank str ? return val; } // convert //--------------------------------------- forall( E | { int ?