source: libcfa/src/stdlib.cfa@ 210b8b3

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since 210b8b3 was e3fea42, checked in by Peter A. Buhr <pabuhr@…>, 6 years ago

change "const char *" to "const char []"

  • Property mode set to 100644
File size: 8.6 KB
Line 
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//
7// stdlib.c --
8//
9// Author : Peter A. Buhr
10// Created On : Thu Jan 28 17:10:29 2016
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Tue Feb 4 08:27:08 2020
13// Update Count : 486
14//
15
16#include "stdlib.hfa"
17
18//---------------------------------------
19
20#define _XOPEN_SOURCE 600 // posix_memalign, *rand48
21#include <string.h> // memcpy, memset
22#include <malloc.h> // malloc_usable_size
23//#include <math.h> // fabsf, fabs, fabsl
24#include <complex.h> // _Complex_I
25#include <assert.h>
26
27//---------------------------------------
28
29forall( dtype T | sized(T) ) {
30 T * alloc_set( T ptr[], size_t dim, char fill ) { // realloc array with fill
31 size_t olen = malloc_usable_size( ptr ); // current allocation
32 void * nptr = (void *)realloc( (void *)ptr, dim * sizeof(T) ); // C realloc
33 size_t nlen = malloc_usable_size( nptr ); // new allocation
34 if ( nlen > olen ) { // larger ?
35 memset( (char *)nptr + olen, (int)fill, nlen - olen ); // initialize added storage
36 } // if
37 return (T *)nptr;
38 } // alloc_set
39
40 T * alloc_align_set( T ptr[], size_t align, char fill ) { // aligned realloc with fill
41 size_t olen = malloc_usable_size( ptr ); // current allocation
42 void * nptr = (void *)realloc( (void *)ptr, align, sizeof(T) ); // CFA realloc
43 // char * nptr = alloc_align( ptr, align );
44 size_t nlen = malloc_usable_size( nptr ); // new allocation
45 if ( nlen > olen ) { // larger ?
46 memset( (char *)nptr + olen, (int)fill, nlen - olen ); // initialize added storage
47 } // if
48 return (T *)nptr;
49 } // alloc_align_set
50} // distribution
51
52// allocation/deallocation and constructor/destructor, non-array types
53forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } )
54T * new( Params p ) {
55 return &(*malloc()){ p }; // run constructor
56} // new
57
58forall( dtype T | sized(T) | { void ^?{}( T & ); } )
59void delete( T * ptr ) {
60 if ( ptr ) { // ignore null
61 ^(*ptr){}; // run destructor
62 free( ptr );
63 } // if
64} // delete
65
66forall( dtype T, ttype Params | sized(T) | { void ^?{}( T & ); void delete( Params ); } )
67void delete( T * ptr, Params rest ) {
68 if ( ptr ) { // ignore null
69 ^(*ptr){}; // run destructor
70 free( ptr );
71 } // if
72 delete( rest );
73} // delete
74
75
76// allocation/deallocation and constructor/destructor, array types
77forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } )
78T * anew( size_t dim, Params p ) {
79 T * arr = alloc( dim );
80 for ( unsigned int i = 0; i < dim; i += 1 ) {
81 (arr[i]){ p }; // run constructor
82 } // for
83 return arr;
84} // anew
85
86forall( dtype T | sized(T) | { void ^?{}( T & ); } )
87void adelete( size_t dim, T arr[] ) {
88 if ( arr ) { // ignore null
89 for ( int i = dim - 1; i >= 0; i -= 1 ) { // reverse allocation order, must be unsigned
90 ^(arr[i]){}; // run destructor
91 } // for
92 free( arr );
93 } // if
94} // adelete
95
96forall( dtype T | sized(T) | { void ^?{}( T & ); }, ttype Params | { void adelete( Params ); } )
97void adelete( size_t dim, T arr[], Params rest ) {
98 if ( arr ) { // ignore null
99 for ( int i = dim - 1; i >= 0; i -= 1 ) { // reverse allocation order, must be unsigned
100 ^(arr[i]){}; // run destructor
101 } // for
102 free( arr );
103 } // if
104 adelete( rest );
105} // adelete
106
107//---------------------------------------
108
109float _Complex strto( const char sptr[], char ** eptr ) {
110 float re, im;
111 char * eeptr;
112 re = strtof( sptr, &eeptr );
113 if ( sptr == eeptr ) { if ( eptr != 0 ) *eptr = eeptr; return 0.0f + 0.0f * _Complex_I; }
114 im = strtof( eeptr, &eeptr );
115 if ( sptr == eeptr ) { if ( eptr != 0 ) *eptr = eeptr; return 0.0f + 0.0f * _Complex_I; }
116 if ( *eeptr != 'i' ) { if ( eptr != 0 ) *eptr = eeptr; return 0.0f + 0.0f * _Complex_I; }
117 return re + im * _Complex_I;
118} // strto
119
120double _Complex strto( const char sptr[], char ** eptr ) {
121 double re, im;
122 char * eeptr;
123 re = strtod( sptr, &eeptr );
124 if ( sptr == eeptr ) { if ( eptr != 0 ) *eptr = eeptr; return 0.0 + 0.0 * _Complex_I; }
125 im = strtod( eeptr, &eeptr );
126 if ( sptr == eeptr ) { if ( eptr != 0 ) *eptr = eeptr; return 0.0 + 0.0 * _Complex_I; }
127 if ( *eeptr != 'i' ) { if ( eptr != 0 ) *eptr = eeptr; return 0.0 + 0.0 * _Complex_I; }
128 return re + im * _Complex_I;
129} // strto
130
131long double _Complex strto( const char sptr[], char ** eptr ) {
132 long double re, im;
133 char * eeptr;
134 re = strtold( sptr, &eeptr );
135 if ( sptr == eeptr ) { if ( eptr != 0 ) *eptr = eeptr; return 0.0L + 0.0L * _Complex_I; }
136 im = strtold( eeptr, &eeptr );
137 if ( sptr == eeptr ) { if ( eptr != 0 ) *eptr = eeptr; return 0.0L + 0.0L * _Complex_I; }
138 if ( *eeptr != 'i' ) { if ( eptr != 0 ) *eptr = eeptr; return 0.0L + 0.0L * _Complex_I; }
139 return re + im * _Complex_I;
140} // strto
141
142//---------------------------------------
143
144forall( otype E | { int ?<?( E, E ); } ) {
145 E * bsearch( E key, const E * vals, size_t dim ) {
146 int cmp( const void * t1, const void * t2 ) {
147 return *(E *)t1 < *(E *)t2 ? -1 : *(E *)t2 < *(E *)t1 ? 1 : 0;
148 } // cmp
149 return (E *)bsearch( &key, vals, dim, sizeof(E), cmp );
150 } // bsearch
151
152 size_t bsearch( E key, const E * vals, size_t dim ) {
153 E * result = bsearch( key, vals, dim );
154 return result ? result - vals : dim; // pointer subtraction includes sizeof(E)
155 } // bsearch
156
157 size_t bsearchl( E key, const E * vals, size_t dim ) {
158 size_t l = 0, m, h = dim;
159 while ( l < h ) {
160 m = (l + h) / 2;
161 if ( (E &)(vals[m]) < key ) { // cast away const
162 l = m + 1;
163 } else {
164 h = m;
165 } // if
166 } // while
167 return l;
168 } // bsearchl
169
170 E * bsearchl( E key, const E * vals, size_t dim ) {
171 size_t posn = bsearchl( key, vals, dim );
172 return (E *)(&vals[posn]); // cast away const
173 } // bsearchl
174
175 size_t bsearchu( E key, const E * vals, size_t dim ) {
176 size_t l = 0, m, h = dim;
177 while ( l < h ) {
178 m = (l + h) / 2;
179 if ( ! ( key < (E &)(vals[m]) ) ) { // cast away const
180 l = m + 1;
181 } else {
182 h = m;
183 } // if
184 } // while
185 return l;
186 } // bsearchu
187
188 E * bsearchu( E key, const E * vals, size_t dim ) {
189 size_t posn = bsearchu( key, vals, dim );
190 return (E *)(&vals[posn]);
191 } // bsearchu
192
193
194 void qsort( E * vals, size_t dim ) {
195 int cmp( const void * t1, const void * t2 ) {
196 return *(E *)t1 < *(E *)t2 ? -1 : *(E *)t2 < *(E *)t1 ? 1 : 0;
197 } // cmp
198 qsort( vals, dim, sizeof(E), cmp );
199 } // qsort
200} // distribution
201
202
203forall( otype K, otype E | { int ?<?( K, K ); K getKey( const E & ); } ) {
204 E * bsearch( K key, const E * vals, size_t dim ) {
205 int cmp( const void * t1, const void * t2 ) {
206 return *(K *)t1 < getKey( *(E *)t2 ) ? -1 : getKey( *(E *)t2 ) < *(K *)t1 ? 1 : 0;
207 } // cmp
208 return (E *)bsearch( &key, vals, dim, sizeof(E), cmp );
209 } // bsearch
210
211 size_t bsearch( K key, const E * vals, size_t dim ) {
212 E * result = bsearch( key, vals, dim );
213 return result ? result - vals : dim; // pointer subtraction includes sizeof(E)
214 } // bsearch
215
216 size_t bsearchl( K key, const E * vals, size_t dim ) {
217 size_t l = 0, m, h = dim;
218 while ( l < h ) {
219 m = (l + h) / 2;
220 if ( getKey( vals[m] ) < key ) {
221 l = m + 1;
222 } else {
223 h = m;
224 } // if
225 } // while
226 return l;
227 } // bsearchl
228
229 E * bsearchl( K key, const E * vals, size_t dim ) {
230 size_t posn = bsearchl( key, vals, dim );
231 return (E *)(&vals[posn]); // cast away const
232 } // bsearchl
233
234 size_t bsearchu( K key, const E * vals, size_t dim ) {
235 size_t l = 0, m, h = dim;
236 while ( l < h ) {
237 m = (l + h) / 2;
238 if ( ! ( key < getKey( vals[m] ) ) ) {
239 l = m + 1;
240 } else {
241 h = m;
242 } // if
243 } // while
244 return l;
245 } // bsearchu
246
247 E * bsearchu( K key, const E * vals, size_t dim ) {
248 size_t posn = bsearchu( key, vals, dim );
249 return (E *)(&vals[posn]);
250 } // bsearchu
251} // distribution
252
253//---------------------------------------
254
255extern "C" { // override C version
256 void srandom( unsigned int seed ) { srand48( (long int)seed ); }
257 long int random( void ) { return mrand48(); }
258} // extern "C"
259
260float random( void ) { return (float)drand48(); } // cast otherwise float uses lrand48
261double random( void ) { return drand48(); }
262float _Complex random( void ) { return (float)drand48() + (float _Complex)(drand48() * _Complex_I); }
263double _Complex random( void ) { return drand48() + (double _Complex)(drand48() * _Complex_I); }
264long double _Complex random( void ) { return (long double)drand48() + (long double _Complex)(drand48() * _Complex_I); }
265
266//---------------------------------------
267
268bool threading_enabled(void) __attribute__((weak)) {
269 return false;
270}
271
272// Local Variables: //
273// tab-width: 4 //
274// End: //
Note: See TracBrowser for help on using the repository browser.