Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/stdlib.hfa

    r4a3eb1c rfbe3f03  
    1010// Created On       : Thu Jan 28 17:12:35 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Apr 23 14:05:21 2024
    13 // Update Count     : 963
     12// Last Modified On : Mon Apr 15 22:11:51 2024
     13// Update Count     : 817
    1414//
    1515
     
    4747
    4848static inline forall( T & | sized(T) ) {
    49         // CFA safe equivalents, i.e., implicit size specification, eliminate return-type cast
     49        // CFA safe equivalents, i.e., implicit size specification
    5050
    5151        T * malloc( void ) {
     
    6464        } // calloc
    6565
    66         T * resize( T * ptr, size_t size ) {
    67                 if ( _Alignof(T) <= libAlign() ) return (T *)resize( (void *)ptr, size ); // C resize
     66        T * resize( T * ptr, size_t size ) {                            // CFA resize
     67                if ( _Alignof(T) <= libAlign() ) return (T *)resize( (void *)ptr, size ); // CFA resize
    6868                else return (T *)resize( (void *)ptr, _Alignof(T), size ); // CFA resize
    69         } // resize
    70 
    71         T * resize( T * ptr, size_t alignment, size_t size ) {
    72                 return (T *)resize( (void *)ptr, alignment, size ); // CFA resize
    7369        } // resize
    7470
     
    7874        } // realloc
    7975
    80         T * realloc( T * ptr, size_t alignment, size_t size ) {
    81                 return (T *)realloc( (void *)ptr, alignment, size ); // CFA realloc
    82         } // realloc
    83 
    8476        T * reallocarray( T * ptr, size_t dim ) {                       // CFA reallocarray
    8577                if ( _Alignof(T) <= libAlign() ) return (T *)reallocarray( (void *)ptr, dim, sizeof(T) ); // C reallocarray
     
    8779        } // realloc
    8880
    89         T * reallocarray( T * ptr, size_t alignment, size_t dim ) {
    90                 return (T *)reallocarray( (void *)ptr, alignment, dim ); // CFA reallocarray
    91         } // realloc
    92 
    9381        T * memalign( size_t align ) {
    9482                return (T *)memalign( align, sizeof(T) );               // C memalign
     
    9987        } // amemalign
    10088
    101         T * cmemalign( size_t align, size_t dim ) {
     89        T * cmemalign( size_t align, size_t dim  ) {
    10290                return (T *)cmemalign( align, dim, sizeof(T) ); // CFA cmemalign
    10391        } // cmemalign
     
    121109
    122110/*
    123         FIX ME : fix alloc interface after Ticker Number 214 is resolved, define and add union to S_fill. Then, modify
    124         postfix-fill functions to support T * with nmemb, char, and T object of any size. Finally, change alloc_internal.
     111        FIX ME : fix alloc interface after Ticker Number 214 is resolved, define and add union to S_fill. Then, modify postfix-fill functions to support T * with nmemb, char, and T object of any size. Finally, change alloc_internal.
    125112        Or, just follow the instructions below for that.
    126113
     
    166153*/
    167154
    168 #pragma GCC diagnostic push
    169 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
    170 #pragma GCC diagnostic ignored "-Wuninitialized"
    171 
    172 struct T_align { size_t align; };
    173 struct T_resize { void * addr; };
    174 struct T_realloc { void * addr; };
    175 forall( T & ) struct T_fill {
    176         // 'N' => no fill, 'c' => fill with character c, 'a' => fill first N array elements from another array,
    177         // 'A' => fill all array elements from another array, 'T' => fill using a T value.
    178         char tag;
    179         size_t nelem;   // number of elements copied from "at" (used with tag 'a')
    180 //      union {
    181                 char c;
    182                 T * at;
    183                 char t[64]; // T t;
    184 //      };
    185 };
    186 
    187 #pragma GCC diagnostic pop
    188 
    189 static inline {
    190         T_align ?`align( size_t a ) { return (T_align){ a }; }
    191         T_resize ?`resize( void * a ) { return (T_resize){ a }; }
    192         T_realloc ?`realloc( void * a ) { return (T_realloc){ a }; }
     155typedef struct S_align { inline size_t;  } T_align;
     156typedef struct S_resize { inline void *;  }     T_resize;
     157
     158forall( T & ) {
     159        struct S_fill { char tag; char c; size_t size; T * at; char t[50]; };
     160        struct S_realloc { inline T *; };
    193161}
    194162
     163static inline T_align ?`align( size_t a ) { return (T_align){a}; }
     164static inline T_resize ?`resize( void * a )     { return (T_resize){a}; }
     165
     166extern "C" ssize_t write(int fd, const void *buf, size_t count);
    195167static inline forall( T & | sized(T) ) {
    196         T_fill(T) ?`fill( char c ) { return (T_fill(T)){ 'c', 0, c }; }
    197         T_fill(T) ?`fill( T t ) {
    198                 T_fill(T) ret = { 'T' };
     168        S_fill(T) ?`fill ( T t ) {
     169                S_fill(T) ret = { 't' };
    199170                size_t size = sizeof(T);
    200171                if ( size > sizeof(ret.t) ) {
     
    204175                return ret;
    205176        }
    206         T_fill(T) ?`fill( T a[] ) { return (T_fill(T)){ 'A', 0, '\0', a }; } // FIX ME: remove this once ticket 214 is resolved
    207         T_fill(T) ?`fill( T a[], size_t nelem ) { return (T_fill(T)){ 'a', nelem * sizeof(T), '\0', a }; }
    208 
    209         // private interface
    210         T * alloc_internal$( size_t Dim, T_resize Resize, T_realloc Realloc, size_t Align, T_fill(T) Fill ) {
    211                 T * ptr;
    212                 size_t tsize = sizeof(T);
     177        S_fill(T) ?`fill ( zero_t ) = void; // FIX ME: remove this once ticket 214 is resolved
     178        S_fill(T) ?`fill ( T * a ) { return (S_fill(T)){ 'T', '0', 0, a }; } // FIX ME: remove this once ticket 214 is resolved
     179        S_fill(T) ?`fill ( char c ) { return (S_fill(T)){ 'c', c };     }
     180        S_fill(T) ?`fill ( T a[], size_t nmemb ) { return (S_fill(T)){ 'a', '0', nmemb * sizeof(T), a }; }
     181
     182        S_realloc(T) ?`realloc ( T * a ) { return (S_realloc(T)){a}; }
     183
     184        T * alloc_internal$( void * Resize, T * Realloc, size_t Align, size_t Dim, S_fill(T) Fill ) {
     185                T * ptr = NULL;
     186                size_t size = sizeof(T);
    213187                size_t copy_end = 0;
    214188
    215                 if ( Resize.addr ) {
    216                         ptr = (T *)(void *)resize( Resize.addr, Align, Dim * tsize );
    217                 } else if ( Realloc.addr ) {
    218                         if ( Fill.tag != 'N' ) copy_end = min(malloc_size( Realloc.addr ), Dim * tsize );
    219                         ptr = (T *)(void *)realloc( Realloc.addr, Align, Dim * tsize );
     189                if ( Resize ) {
     190                        ptr = (T*)(void *)resize( (void *)Resize, Align, Dim * size );
     191                } else if ( Realloc ) {
     192                        if ( Fill.tag != '0' ) copy_end = min(malloc_size( Realloc ), Dim * size );
     193                        ptr = (T *)(void *)realloc( (void *)Realloc, Align, Dim * size );
    220194                } else {
    221                         ptr = (T *)(void *)memalign( Align, Dim * tsize );
    222                 } // if
     195                        ptr = (T *)(void *) memalign( Align, Dim * size );
     196                }
    223197
    224198                if ( Fill.tag == 'c' ) {
    225                         memset( (char *)ptr + copy_end, (int)Fill.c, Dim * tsize - copy_end );
     199                        memset( (char *)ptr + copy_end, (int)Fill.c, Dim * size - copy_end );
     200                } else if ( Fill.tag == 't' ) {
     201                        for ( i; copy_end ~ Dim * size ~ size ) {
     202                                #pragma GCC diagnostic push
     203                                #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
     204                                assert( size <= sizeof(Fill.t) );
     205                                memcpy( (char *)ptr + i, &Fill.t, size );
     206                                #pragma GCC diagnostic pop
     207                        }
     208                } else if ( Fill.tag == 'a' ) {
     209                        memcpy( (char *)ptr + copy_end, Fill.at, min(Dim * size - copy_end, Fill.size) );
    226210                } else if ( Fill.tag == 'T' ) {
    227                         for ( i; copy_end ~ Dim * tsize ~ tsize ) {
    228                                 assert( tsize <= sizeof(Fill.t) );
    229                                 memcpy( (char *)ptr + i, &Fill.t, tsize );
    230                         } // for
    231                 } else if ( Fill.tag == 'a' ) {
    232                         memcpy( (char *)ptr + copy_end, Fill.at, min( Dim * tsize - copy_end, Fill.nelem ) );
    233                 } else if ( Fill.tag == 'A' ) {
    234                         memcpy( (char *)ptr + copy_end, Fill.at, Dim * tsize );
    235                 } // if
     211                        memcpy( (char *)ptr + copy_end, Fill.at, Dim * size );
     212                }
     213
    236214                return ptr;
    237215        } // alloc_internal$
    238216
    239         // Dim is a fixed (optional first) parameter, and hence is not set using a postfix function. A dummy parameter is
    240         // being overwritten by the postfix argument in the ttype.
    241         forall( List ... | { T * alloc_internal$( size_t Dim, T_resize Resize, T_realloc Realloc, size_t Align, T_fill(T) Fill, List ); } ) {
    242                 // middle interface
    243                 T * alloc_internal$( size_t Dim, T_resize dummy, T_realloc Realloc, size_t Align, T_fill(T) Fill, T_resize Resize, List rest ) {
    244                 return alloc_internal$( Dim, Resize, (T_realloc){0p}, Align, Fill, rest );
    245                 }
    246                 T * alloc_internal$( size_t Dim, T_resize Resize, T_realloc dummy, size_t Align, T_fill(T) Fill, T_realloc Realloc, List rest ) {
    247                 return alloc_internal$( Dim, (T_resize){0p}, Realloc, Align, Fill, rest );
    248                 }
    249                 T * alloc_internal$( size_t Dim, T_resize Resize, T_realloc Realloc, size_t dummy, T_fill(T) Fill, T_align Align, List rest ) {
    250                 return alloc_internal$( Dim, Resize, Realloc, Align.align, Fill, rest );
    251                 }
    252                 T * alloc_internal$( size_t Dim, T_resize Resize, T_realloc Realloc, size_t Align, T_fill(T) dummy, T_fill(T) Fill, List rest ) {
    253                 return alloc_internal$( Dim, Resize, Realloc, Align, Fill, rest );
    254                 }
    255                 // public interface
    256             T * alloc( List rest ) {
    257                 return alloc_internal$( (size_t)1, (T_resize){0p}, (T_realloc){0p}, (_Alignof(T) > libAlign() ? _Alignof(T) : libAlign()), (T_fill(T)){'N'}, rest );
     217        forall( TT ... | { T * alloc_internal$( void *, T *, size_t, size_t, S_fill(T), TT ); } ) {
     218                T * alloc_internal$( void *, T *, size_t Align, size_t Dim, S_fill(T) Fill, T_resize Resize, TT rest ) {
     219                return alloc_internal$( Resize, (T*)0p, Align, Dim, Fill, rest);
     220                }
     221
     222                T * alloc_internal$( void *, T *, size_t Align, size_t Dim, S_fill(T) Fill, S_realloc(T) Realloc, TT rest ) {
     223                return alloc_internal$( (void*)0p, Realloc, Align, Dim, Fill, rest);
     224                }
     225
     226                T * alloc_internal$( void * Resize, T * Realloc, size_t, size_t Dim, S_fill(T) Fill, T_align Align, TT rest ) {
     227                return alloc_internal$( Resize, Realloc, Align, Dim, Fill, rest);
     228                }
     229
     230                T * alloc_internal$( void * Resize, T * Realloc, size_t Align, size_t Dim, S_fill(T), S_fill(T) Fill, TT rest ) {
     231                return alloc_internal$( Resize, Realloc, Align, Dim, Fill, rest );
     232                }
     233
     234            T * alloc( TT all ) {
     235                return alloc_internal$( (void*)0p, (T*)0p, (_Alignof(T) > libAlign() ? _Alignof(T) : libAlign()), (size_t)1, (S_fill(T)){'0'}, all );
    258236            }
    259             T * alloc( size_t Dim, List rest ) {
    260                 return alloc_internal$( Dim, (T_resize){0p}, (T_realloc){0p}, (_Alignof(T) > libAlign() ? _Alignof(T) : libAlign()), (T_fill(T)){'N'}, rest );
     237
     238            T * alloc( size_t dim, TT all ) {
     239                return alloc_internal$( (void*)0p, (T*)0p, (_Alignof(T) > libAlign() ? _Alignof(T) : libAlign()), dim, (S_fill(T)){'0'}, all );
    261240            }
    262         } // distribution List
     241        } // distribution TT
    263242} // distribution T
    264243
    265244static inline forall( T & | sized(T) ) {
    266245        // CFA safe initialization/copy, i.e., implicit size specification, non-array types
    267         T * memset( T * dest, char fill ) {                                     // all combinations of pointer/reference
    268                 return (T *)memset( dest, fill, sizeof(T) );    // C memset
     246        T * memset( T * dest, char fill ) {
     247                return (T *)memset( dest, fill, sizeof(T) );
    269248        } // memset
    270         T * memset( T & dest, char fill ) {
    271                 return (T *)memset( &dest, fill, sizeof(T) );   // C memset
    272         } // memset
    273 
    274         T * memcpy( T * dest, const T * src ) {                         // all combinations of pointer/reference
    275                 return (T *)memcpy( dest, src, sizeof(T) );             // C memcpy
    276         } // memcpy
    277         T * memcpy( T & dest, const T & src ) {
    278                 return (T *)memcpy( &dest, &src, sizeof(T) );   // C memcpy
    279         } // memcpy
    280         T * memcpy( T * dest, const T & src ) {
    281                 return (T *)memcpy( dest, &src, sizeof(T) );    // C memcpy
    282         } // memcpy
    283         T * memcpy( T & dest, const T * src ) {
    284                 return (T *)memcpy( &dest, src, sizeof(T) );    // C memcpy
     249
     250        T * memcpy( T * dest, const T * src ) {
     251                return (T *)memcpy( dest, src, sizeof(T) );
    285252        } // memcpy
    286253
     
    296263
    297264// CFA deallocation for multiple objects
    298 static inline forall( T & )
     265static inline forall( T & )                                                     // FIX ME, problems with 0p in list
    299266void free( T * ptr ) {
    300267        free( (void *)ptr );                                                            // C free
    301268} // free
    302 static inline forall( T &, List ... | { void free( List ); } )
    303 void free( T * ptr, List rest ) {
     269static inline forall( T &, TT ... | { void free( TT ); } )
     270void free( T * ptr, TT rest ) {
    304271        free( ptr );
    305272        free( rest );
     
    307274
    308275// CFA allocation/deallocation and constructor/destructor, non-array types
    309 static inline forall( T & | sized(T), Parms ... | { void ?{}( T &, Parms ); } )
    310 T * new( Parms p ) {
     276static inline forall( T & | sized(T), TT ... | { void ?{}( T &, TT ); } )
     277T * new( TT p ) {
    311278        return &(*(T *)malloc()){ p };                                          // run constructor
    312279} // new
     
    320287        free( ptr );                                                                            // always call free
    321288} // delete
    322 static inline forall( T &, List ... | { void ^?{}( T & ); void delete( List ); } )
    323 void delete( T * ptr, List rest ) {
     289static inline forall( T &, TT ... | { void ^?{}( T & ); void delete( TT ); } )
     290void delete( T * ptr, TT rest ) {
    324291        delete( ptr );
    325292        delete( rest );
     
    327294
    328295// CFA allocation/deallocation and constructor/destructor, array types
    329 forall( T & | sized(T), Parms ... | { void ?{}( T &, Parms ); } ) T * anew( size_t dim, Parms p );
     296forall( T & | sized(T), TT ... | { void ?{}( T &, TT ); } ) T * anew( size_t dim, TT p );
    330297forall( T & | sized(T) | { void ^?{}( T & ); } ) void adelete( T arr[] );
    331 forall( T & | sized(T) | { void ^?{}( T & ); }, List ... | { void adelete( List ); } ) void adelete( T arr[], List rest );
    332 
     298forall( T & | sized(T) | { void ^?{}( T & ); }, TT ... | { void adelete( TT ); } ) void adelete( T arr[], TT rest );
    333299//---------------------------------------
    334300
Note: See TracChangeset for help on using the changeset viewer.