source: libcfa/src/stdlib.cfa@ 3ad5c50

Last change on this file since 3ad5c50 was 54af365, checked in by Peter A. Buhr <pabuhr@…>, 19 months ago

fix convert function for float-point values, add isspace-like routines for C arrays

  • Property mode set to 100644
File size: 10.3 KB
RevLine 
[bd85400]1//
2// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
[f4a6101]7// stdlib.c --
[bd85400]8//
9// Author : Peter A. Buhr
10// Created On : Thu Jan 28 17:10:29 2016
[e310238]11// Last Modified By : Peter A. Buhr
[54af365]12// Last Modified On : Fri Mar 15 18:47:28 2024
13// Update Count : 685
[bd85400]14//
15
[58b6d1b]16#include "stdlib.hfa"
[5d1ebb9]17#include "bits/random.hfa"
[2210cfc]18#include "concurrency/invoke.h" // random_state
[bd85400]19
20//---------------------------------------
21
[f3fc631f]22#include <string.h> // memcpy, memset
[89124ff]23//#include <math.h> // fabsf, fabs, fabsl
[6e991d6]24#include <complex.h> // _Complex_I
[e672372]25#include <assert.h>
[54af365]26#include <ctype.h>
[bd85400]27
[0aa4beb]28#pragma GCC visibility push(default)
29
[f4a6101]30//---------------------------------------
31
[94429f8]32// Cforall allocation/deallocation and constructor/destructor, array types
[627f585]33
[fd54fef]34forall( T & | sized(T), TT... | { void ?{}( T &, TT ); } )
[94429f8]35T * anew( size_t dim, TT p ) {
[6887a99]36 T * arr = alloc( dim );
[f6a4917]37 for ( i; dim ) {
[a493682]38 (arr[i]){ p }; // run constructor
[6065b3aa]39 } // for
40 return arr;
41} // anew
42
[fd54fef]43forall( T & | sized(T) | { void ^?{}( T & ); } )
[45444c3]44void adelete( T arr[] ) {
[6065b3aa]45 if ( arr ) { // ignore null
[45444c3]46 size_t dim = malloc_size( arr ) / sizeof( T );
[f6a4917]47 for ( i; 0 -~= dim - 1 ) { // reverse allocation order, must be unsigned
[a493682]48 ^(arr[i]){}; // run destructor
[6065b3aa]49 } // for
50 free( arr );
51 } // if
52} // adelete
53
[fd54fef]54forall( T & | sized(T) | { void ^?{}( T & ); }, TT... | { void adelete( TT ); } )
[94429f8]55void adelete( T arr[], TT rest ) {
[6065b3aa]56 if ( arr ) { // ignore null
[45444c3]57 size_t dim = malloc_size( arr ) / sizeof( T );
[f6a4917]58 for ( i; 0 -~= dim - 1 ) { // reverse allocation order, must be unsigned
[a493682]59 ^(arr[i]){}; // run destructor
[6065b3aa]60 } // for
61 free( arr );
62 } // if
63 adelete( rest );
64} // adelete
65
[bd85400]66//---------------------------------------
67
[54af365]68// Cannot overload with singular (isspace) counterparts because they are macros.
69
70bool isalnums( const char s[] ) {
71 for () {
72 if ( *s == '\0' ) return true;
73 if ( ! isalnum( *s ) ) return false;
74 s += 1;
75 } // for
76} // isalnums
77
78bool isalphas( const char s[] ) {
79 for () {
80 if ( *s == '\0' ) return true;
81 if ( ! isalpha( *s ) ) return false;
82 s += 1;
83 } // for
84} // isblanks
85
86bool iscntrls( const char s[] ) {
87 for () {
88 if ( *s == '\0' ) return true;
89 if ( ! iscntrl( *s ) ) return false;
90 s += 1;
91 } // for
92} // iscntrls
93
94bool isdigits( const char s[] ) {
95 for () {
96 if ( *s == '\0' ) return true;
97 if ( ! isdigit( *s ) ) return false;
98 s += 1;
99 } // for
100} // isdigits
101
102bool isgraphs( const char s[] ) {
103 for () {
104 if ( *s == '\0' ) return true;
105 if ( ! isgraph( *s ) ) return false;
106 s += 1;
107 } // for
108} // isgraphs
109
110bool islowers( const char s[] ) {
111 for () {
112 if ( *s == '\0' ) return true;
113 if ( ! islower( *s ) ) return false;
114 s += 1;
115 } // for
116} // islowers
117
118bool isprints( const char s[] ) {
119 for () {
120 if ( *s == '\0' ) return true;
121 if ( ! isprint( *s ) ) return false;
122 s += 1;
123 } // for
124} // isprints
125
126bool ispuncts( const char s[] ) {
127 for () {
128 if ( *s == '\0' ) return true;
129 if ( ! ispunct( *s ) ) return false;
130 s += 1;
131 } // for
132} // ispuncts
133
134bool isspaces( const char s[] ) {
135 for () {
136 if ( *s == '\0' ) return true;
137 if ( ! isspace( *s ) ) return false;
138 s += 1;
139 } // for
140} // isspaces
141
142bool isblanks( const char s[] ) {
143 for () {
144 if ( *s == '\0' ) return true;
145 if ( ! isblank( *s ) ) return false;
146 s += 1;
147 } // for
148} // isblanks
149
150bool isuppers( const char s[] ) {
151 for () {
152 if ( *s == '\0' ) return true;
153 if ( ! isupper( *s ) ) return false;
154 s += 1;
155 } // for
156} // isuppers
157
158bool isxdigits( const char s[] ) {
159 for () {
160 if ( *s == '\0' ) return true;
161 if ( ! isxdigit( *s ) ) return false;
162 s += 1;
163 } // for
164} // isxdigits
165
166//---------------------------------------
[76acb60]167
168float _Complex strto( const char sptr[], char * eptr[] ) {
[bd85400]169 float re, im;
[e672372]170 char * eeptr;
[54af365]171 errno = 0; // reset
[e672372]172 re = strtof( sptr, &eeptr );
[54af365]173 if ( sptr != eeptr ) {
174 im = strtof( eeptr, &eeptr );
175 if ( sptr != eeptr ) {
176 if ( *eeptr == 'i' ) {
177 if ( eptr != 0p ) *eptr = eeptr + 1;
178 return re + im * _Complex_I;
179 } // if
180 } // if
181 } // if
182 if ( eptr != 0p ) *eptr = eeptr; // error case
183 return 0.0f + 0.0f * _Complex_I;
[f3ddc21]184} // strto
185
[76acb60]186double _Complex strto( const char sptr[], char * eptr[] ) {
[bd85400]187 double re, im;
[e672372]188 char * eeptr;
189 re = strtod( sptr, &eeptr );
[54af365]190 if ( sptr != eeptr ) {
191 im = strtod( eeptr, &eeptr );
192 if ( sptr != eeptr ) {
193 if ( *eeptr == 'i' ) {
194 if ( eptr != 0p ) *eptr = eeptr + 1;
195 return re + im * _Complex_I;
196 } // if
197 } // if
198 } // if
199 if ( eptr != 0p ) *eptr = eeptr; // error case
200 return 0.0 + 0.0 * _Complex_I;
[f3ddc21]201} // strto
202
[76acb60]203long double _Complex strto( const char sptr[], char * eptr[] ) {
[bd85400]204 long double re, im;
[e672372]205 char * eeptr;
206 re = strtold( sptr, &eeptr );
[54af365]207 if ( sptr != eeptr ) {
208 im = strtold( eeptr, &eeptr );
209 if ( sptr != eeptr ) {
210 if ( *eeptr == 'i' ) {
211 if ( eptr != 0p ) *eptr = eeptr + 1;
212 return re + im * _Complex_I;
213 } // if
214 } // if
215 } // if
216 if ( eptr != 0p ) *eptr = eeptr; // error case
217 return 0.0L + 0.0L * _Complex_I;
[f3ddc21]218} // strto
[bd85400]219
[54af365]220forall( T | { T strto( const char sptr[], char * eptr[], int ); } )
221T convert( const char sptr[] ) { // integral
222 char * eptr;
223 errno = 0; // reset
224 T val = strto( sptr, &eptr, 10 ); // attempt conversion
225 if ( errno == ERANGE ) throw ExceptionInst( out_of_range );
226 if ( eptr == sptr || // conversion failed, no characters generated
227 eptr[0] != '\0' && ! isspaces( eptr ) ) throw ExceptionInst( invalid_argument ); // not at end of blank str ?
228 return val;
229} // convert
230
231forall( T | { T strto( const char sptr[], char * eptr[] ); } )
232T convert( const char sptr[] ) { // floating-point
233 char * eptr;
234 errno = 0; // reset
235 T val = strto( sptr, &eptr ); // attempt conversion
236 if ( errno == ERANGE ) throw ExceptionInst( out_of_range );
237 if ( eptr == sptr || // conversion failed, no characters generated
238 eptr[0] != '\0' && ! isspaces( eptr ) ) throw ExceptionInst( invalid_argument ); // not at end of blank str ?
239 return val;
240} // convert
241
[bd85400]242//---------------------------------------
243
[fd54fef]244forall( E | { int ?<?( E, E ); } ) {
[3ce0d440]245 E * bsearch( E key, const E * vals, size_t dim ) {
246 int cmp( const void * t1, const void * t2 ) {
247 return *(E *)t1 < *(E *)t2 ? -1 : *(E *)t2 < *(E *)t1 ? 1 : 0;
248 } // cmp
249 return (E *)bsearch( &key, vals, dim, sizeof(E), cmp );
250 } // bsearch
251
252 size_t bsearch( E key, const E * vals, size_t dim ) {
253 E * result = bsearch( key, vals, dim );
254 return result ? result - vals : dim; // pointer subtraction includes sizeof(E)
255 } // bsearch
256
257 size_t bsearchl( E key, const E * vals, size_t dim ) {
258 size_t l = 0, m, h = dim;
259 while ( l < h ) {
260 m = (l + h) / 2;
261 if ( (E &)(vals[m]) < key ) { // cast away const
262 l = m + 1;
263 } else {
264 h = m;
265 } // if
266 } // while
267 return l;
268 } // bsearchl
269
270 E * bsearchl( E key, const E * vals, size_t dim ) {
271 size_t posn = bsearchl( key, vals, dim );
272 return (E *)(&vals[posn]); // cast away const
273 } // bsearchl
274
275 size_t bsearchu( E key, const E * vals, size_t dim ) {
276 size_t l = 0, m, h = dim;
277 while ( l < h ) {
278 m = (l + h) / 2;
279 if ( ! ( key < (E &)(vals[m]) ) ) { // cast away const
280 l = m + 1;
281 } else {
282 h = m;
283 } // if
284 } // while
285 return l;
286 } // bsearchu
287
288 E * bsearchu( E key, const E * vals, size_t dim ) {
289 size_t posn = bsearchu( key, vals, dim );
290 return (E *)(&vals[posn]);
291 } // bsearchu
292
293
294 void qsort( E * vals, size_t dim ) {
295 int cmp( const void * t1, const void * t2 ) {
296 return *(E *)t1 < *(E *)t2 ? -1 : *(E *)t2 < *(E *)t1 ? 1 : 0;
297 } // cmp
298 qsort( vals, dim, sizeof(E), cmp );
299 } // qsort
300} // distribution
301
302
[fd54fef]303forall( K, E | { int ?<?( K, K ); K getKey( const E & ); } ) {
[3ce0d440]304 E * bsearch( K key, const E * vals, size_t dim ) {
305 int cmp( const void * t1, const void * t2 ) {
306 return *(K *)t1 < getKey( *(E *)t2 ) ? -1 : getKey( *(E *)t2 ) < *(K *)t1 ? 1 : 0;
307 } // cmp
308 return (E *)bsearch( &key, vals, dim, sizeof(E), cmp );
309 } // bsearch
310
311 size_t bsearch( K key, const E * vals, size_t dim ) {
312 E * result = bsearch( key, vals, dim );
313 return result ? result - vals : dim; // pointer subtraction includes sizeof(E)
314 } // bsearch
315
316 size_t bsearchl( K key, const E * vals, size_t dim ) {
317 size_t l = 0, m, h = dim;
318 while ( l < h ) {
319 m = (l + h) / 2;
320 if ( getKey( vals[m] ) < key ) {
321 l = m + 1;
322 } else {
323 h = m;
324 } // if
325 } // while
326 return l;
327 } // bsearchl
328
329 E * bsearchl( K key, const E * vals, size_t dim ) {
330 size_t posn = bsearchl( key, vals, dim );
331 return (E *)(&vals[posn]); // cast away const
332 } // bsearchl
333
334 size_t bsearchu( K key, const E * vals, size_t dim ) {
335 size_t l = 0, m, h = dim;
336 while ( l < h ) {
337 m = (l + h) / 2;
338 if ( ! ( key < getKey( vals[m] ) ) ) {
339 l = m + 1;
340 } else {
341 h = m;
342 } // if
343 } // while
344 return l;
345 } // bsearchu
346
347 E * bsearchu( K key, const E * vals, size_t dim ) {
348 size_t posn = bsearchu( key, vals, dim );
349 return (E *)(&vals[posn]);
350 } // bsearchu
351} // distribution
[bd85400]352
353//---------------------------------------
354
[bbe1a87]355extern "C" { // override C version
356 void srandom( unsigned int seed ) { srand48( (long int)seed ); }
[4e7c0fc0]357 long int random( void ) { return mrand48(); } // GENERATES POSITIVE AND NEGATIVE VALUES
[bbe1a87]358} // extern "C"
359
[e672372]360float random( void ) { return (float)drand48(); } // cast otherwise float uses lrand48
[70e4895d]361double random( void ) { return drand48(); }
362float _Complex random( void ) { return (float)drand48() + (float _Complex)(drand48() * _Complex_I); }
363double _Complex random( void ) { return drand48() + (double _Complex)(drand48() * _Complex_I); }
[e672372]364long double _Complex random( void ) { return (long double)drand48() + (long double _Complex)(drand48() * _Complex_I); }
[a9f2c13]365
[2026bb6]366//---------------------------------------
367
[0aa4beb]368// would be cool to make hidden but it's needed for libcfathread
[dd46fd3]369__attribute__((visibility("default"))) size_t __global_random_seed; // sequential/concurrent
370__attribute__((visibility("hidden"))) PRNG_STATE_T __global_random_state; // sequential only
[aa8e24c3]371
[8a3d5e7]372void set_seed( size_t seed ) {
373 __global_random_seed = seed;
374 PRNG_SET_SEED( __global_random_state, seed );
[4020f09]375} // set_seed
376
[20cf96d]377size_t get_seed() { return __global_random_seed; }
378size_t prng( void ) { return PRNG_NAME( __global_random_state ); } // [0,UINT_MAX]
[aa8e24c3]379
380//---------------------------------------
381
382bool threading_enabled( void ) __attribute__(( weak )) { return false; }
[bd85400]383
384// Local Variables: //
385// tab-width: 4 //
386// End: //
Note: See TracBrowser for help on using the repository browser.