Changeset c08c3cf for libcfa/src/bits


Ignore:
Timestamp:
Jan 20, 2021, 8:46:31 PM (4 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
481cf3a
Parents:
467c8b7 (diff), 9db2c92 (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:

fix conflict

Location:
libcfa/src/bits
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified libcfa/src/bits/algorithm.hfa

    r467c8b7 rc08c3cf  
    1717
    1818#ifdef SAFE_SORT
    19 forall( otype T | {  int ?<?( T, T ); int ?>?( T, T ); } ) static inline void __libcfa_small_sort2( T * arr );
    20 forall( otype T | {  int ?<?( T, T ); int ?>?( T, T ); } ) static inline void __libcfa_small_sort3( T * arr );
    21 forall( otype T | {  int ?<?( T, T ); int ?>?( T, T ); } ) static inline void __libcfa_small_sort4( T * arr );
    22 forall( otype T | {  int ?<?( T, T ); int ?>?( T, T ); } ) static inline void __libcfa_small_sort5( T * arr );
    23 forall( otype T | {  int ?<?( T, T ); int ?>?( T, T ); } ) static inline void __libcfa_small_sort6( T * arr );
    24 forall( otype T | {  int ?<?( T, T ); int ?>?( T, T ); } ) static inline void __libcfa_small_sortN( T * arr, size_t dim );
     19forall( T | {  int ?<?( T, T ); int ?>?( T, T ); } ) static inline void __libcfa_small_sort2( T * arr );
     20forall( T | {  int ?<?( T, T ); int ?>?( T, T ); } ) static inline void __libcfa_small_sort3( T * arr );
     21forall( T | {  int ?<?( T, T ); int ?>?( T, T ); } ) static inline void __libcfa_small_sort4( T * arr );
     22forall( T | {  int ?<?( T, T ); int ?>?( T, T ); } ) static inline void __libcfa_small_sort5( T * arr );
     23forall( T | {  int ?<?( T, T ); int ?>?( T, T ); } ) static inline void __libcfa_small_sort6( T * arr );
     24forall( T | {  int ?<?( T, T ); int ?>?( T, T ); } ) static inline void __libcfa_small_sortN( T * arr, size_t dim );
    2525
    26 forall( otype T | {  int ?<?( T, T ); int ?>?( T, T ); } )
     26forall( T | {  int ?<?( T, T ); int ?>?( T, T ); } )
    2727static inline void __libcfa_small_sort( T * arr, size_t dim ) {
    2828        switch( dim ) {
     
    4141#define SWAP(x,y) { T a = min(arr[x], arr[y]); T b = max(arr[x], arr[y]); arr[x] = a; arr[y] = b;}
    4242
    43 forall( otype T | {  int ?<?( T, T ); int ?>?( T, T ); } )
     43forall( T | {  int ?<?( T, T ); int ?>?( T, T ); } )
    4444static inline void __libcfa_small_sort2( T * arr ) {
    4545        SWAP(0, 1);
    4646}
    4747
    48 forall( otype T | {  int ?<?( T, T ); int ?>?( T, T ); } )
     48forall( T | {  int ?<?( T, T ); int ?>?( T, T ); } )
    4949static inline void __libcfa_small_sort3( T * arr ) {
    5050        SWAP(1, 2);
     
    5353}
    5454
    55 forall( otype T | {  int ?<?( T, T ); int ?>?( T, T ); } )
     55forall( T | {  int ?<?( T, T ); int ?>?( T, T ); } )
    5656static inline void __libcfa_small_sort4( T * arr ) {
    5757        SWAP(0, 1);
     
    6262}
    6363
    64 forall( otype T | {  int ?<?( T, T ); int ?>?( T, T ); } )
     64forall( T | {  int ?<?( T, T ); int ?>?( T, T ); } )
    6565static inline void __libcfa_small_sort5( T * arr ) {
    6666        SWAP(0, 1);
     
    7575}
    7676
    77 forall( otype T | {  int ?<?( T, T ); int ?>?( T, T ); } )
     77forall( T | {  int ?<?( T, T ); int ?>?( T, T ); } )
    7878static inline void __libcfa_small_sort6( T * arr ) {
    7979        SWAP(1, 2);
     
    9191}
    9292
    93 forall( otype T | {  int ?<?( T, T ); int ?>?( T, T ); } )
     93forall( T | {  int ?<?( T, T ); int ?>?( T, T ); } )
    9494static inline void __libcfa_small_sortN( T * arr, size_t dim ) {
    9595        int i, j;
     
    112112static inline void __libcfa_small_sortN( void* * arr, size_t dim );
    113113
    114 forall( dtype T )
     114forall( T & )
    115115static inline void __libcfa_small_sort( T* * arr, size_t dim ) {
    116116        switch( dim ) {
  • TabularUnified libcfa/src/bits/collection.hfa

    r467c8b7 rc08c3cf  
    3131
    3232        // // wrappers to make Collection have T
    33         // forall( dtype T ) {
     33        // forall( T & ) {
    3434        //      T *& Next( T * n ) {
    3535        //              return (T *)Next( (Colable *)n );
     
    7676        } // post: elts = null
    7777
    78         forall( dtype T ) {
     78        forall( T & ) {
    7979                T * Curr( ColIter & ci ) with( ci ) {
    8080                        return (T *)curr;
  • TabularUnified libcfa/src/bits/containers.hfa

    r467c8b7 rc08c3cf  
    2323
    2424#ifdef __cforall
    25         forall(dtype T)
     25        forall(T &)
    2626#else
    2727        #define T void
     
    4040
    4141#ifdef __cforall
    42         // forall(otype T | sized(T))
     42        // forall(T | sized(T))
    4343        // static inline void ?{}(__small_array(T) & this) {}
    4444
    45         forall(dtype T | sized(T))
     45        forall(T & | sized(T))
    4646        static inline T & ?[?]( __small_array(T) & this, __lock_size_t idx ) {
    4747                return ((typeof(this.data))this.data)[idx];
    4848        }
    4949
    50         forall(dtype T | sized(T))
     50        forall(T & | sized(T))
    5151        static inline T & ?[?]( const __small_array(T) & this, __lock_size_t idx ) {
    5252                return ((typeof(this.data))this.data)[idx];
    5353        }
    5454
    55         forall(dtype T)
     55        forall(T &)
    5656        static inline T * begin( const __small_array(T) & this ) {
    5757                return ((typeof(this.data))this.data);
    5858        }
    5959
    60         forall(dtype T | sized(T))
     60        forall(T & | sized(T))
    6161        static inline T * end( const __small_array(T) & this ) {
    6262                return ((typeof(this.data))this.data) + this.size;
     
    6969
    7070#ifdef __cforall
    71         trait is_node(dtype T) {
     71        trait is_node(T &) {
    7272                T *& get_next( T & );
    7373        };
     
    7878//-----------------------------------------------------------------------------
    7979#ifdef __cforall
    80         forall(dtype TYPE)
     80        forall(TYPE &)
    8181        #define T TYPE
    8282#else
     
    9595
    9696#ifdef __cforall
    97         forall(dtype T)
     97        forall(T &)
    9898        static inline void ?{}( __stack(T) & this ) {
    9999                (this.top){ 0p };
    100100        }
    101101
    102         static inline forall( dtype T | is_node(T) ) {
     102        static inline forall( T & | is_node(T) ) {
    103103                void push( __stack(T) & this, T * val ) {
    104104                        verify( !get_next( *val ) );
     
    126126//-----------------------------------------------------------------------------
    127127#ifdef __cforall
    128         forall(dtype TYPE)
     128        forall(TYPE &)
    129129        #define T TYPE
    130130#else
     
    144144
    145145#ifdef __cforall
    146         static inline forall( dtype T | is_node(T) ) {
     146        static inline forall( T & | is_node(T) ) {
    147147                void ?{}( __queue(T) & this ) with( this ) {
    148148                        (this.head){ 1p };
     
    215215//-----------------------------------------------------------------------------
    216216#ifdef __cforall
    217         forall(dtype TYPE)
     217        forall(TYPE &)
    218218        #define T TYPE
    219219        #define __getter_t * [T * & next, T * & prev] ( T & )
     
    237237
    238238#ifdef __cforall
    239         forall(dtype T )
     239        forall(T & )
    240240        static inline [void] ?{}( __dllist(T) & this, * [T * & next, T * & prev] ( T & ) __get ) {
    241241                (this.head){ 0p };
     
    245245        #define next 0
    246246        #define prev 1
    247         static inline forall(dtype T) {
     247        static inline forall(T &) {
    248248                void push_front( __dllist(T) & this, T & node ) with( this ) {
    249249                        verify(__get);
  • TabularUnified libcfa/src/bits/defs.hfa

    r467c8b7 rc08c3cf  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // defs.hfa --
     7// defs.hfa -- Commen macros, functions and typedefs
     8// Most files depend on them and they are always useful to have.
     9//
     10//  *** Must not contain code specific to libcfathread ***
    811//
    912// Author           : Thierry Delisle
     
    6265        #endif
    6366}
     67
     68// pause to prevent excess processor bus usage
     69#if defined( __i386 ) || defined( __x86_64 )
     70        #define Pause() __asm__ __volatile__ ( "pause" : : : )
     71#elif defined( __ARM_ARCH )
     72        #define Pause() __asm__ __volatile__ ( "YIELD" : : : )
     73#else
     74        #error unsupported architecture
     75#endif
  • TabularUnified libcfa/src/bits/locks.hfa

    r467c8b7 rc08c3cf  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // bits/locks.hfa -- Fast internal locks.
     7// bits/locks.hfa -- Basic spinlocks that are reused in the system.
     8// Used for locks that aren't specific to cforall threads and can be used anywhere
     9//
     10//  *** Must not contain code specific to libcfathread ***
    811//
    912// Author           : Thierry Delisle
     
    1922#include "bits/defs.hfa"
    2023#include <assert.h>
    21 
    22 #ifdef __cforall
    23         extern "C" {
    24                 #include <pthread.h>
    25         }
    26 #endif
    27 
    28 // pause to prevent excess processor bus usage
    29 #if defined( __i386 ) || defined( __x86_64 )
    30         #define Pause() __asm__ __volatile__ ( "pause" : : : )
    31 #elif defined( __ARM_ARCH )
    32         #define Pause() __asm__ __volatile__ ( "YIELD" : : : )
    33 #else
    34         #error unsupported architecture
    35 #endif
    3624
    3725struct __spinlock_t {
     
    10492                enable_interrupts_noPoll();
    10593        }
    106 
    107 
    108         #ifdef __CFA_WITH_VERIFY__
    109                 extern bool __cfaabi_dbg_in_kernel();
    110         #endif
    111 
    112         extern "C" {
    113                 char * strerror(int);
    114         }
    115         #define CHECKED(x) { int err = x; if( err != 0 ) abort("KERNEL ERROR: Operation \"" #x "\" return error %d - %s\n", err, strerror(err)); }
    116 
    117         struct __bin_sem_t {
    118                 pthread_mutex_t         lock;
    119                 pthread_cond_t          cond;
    120                 int                     val;
    121         };
    122 
    123         static inline void ?{}(__bin_sem_t & this) with( this ) {
    124                 // Create the mutex with error checking
    125                 pthread_mutexattr_t mattr;
    126                 pthread_mutexattr_init( &mattr );
    127                 pthread_mutexattr_settype( &mattr, PTHREAD_MUTEX_ERRORCHECK_NP);
    128                 pthread_mutex_init(&lock, &mattr);
    129 
    130                 pthread_cond_init (&cond, (const pthread_condattr_t *)0p);  // workaround trac#208: cast should not be required
    131                 val = 0;
    132         }
    133 
    134         static inline void ^?{}(__bin_sem_t & this) with( this ) {
    135                 CHECKED( pthread_mutex_destroy(&lock) );
    136                 CHECKED( pthread_cond_destroy (&cond) );
    137         }
    138 
    139         static inline void wait(__bin_sem_t & this) with( this ) {
    140                 verify(__cfaabi_dbg_in_kernel());
    141                 CHECKED( pthread_mutex_lock(&lock) );
    142                         while(val < 1) {
    143                                 pthread_cond_wait(&cond, &lock);
    144                         }
    145                         val -= 1;
    146                 CHECKED( pthread_mutex_unlock(&lock) );
    147         }
    148 
    149         static inline bool post(__bin_sem_t & this) with( this ) {
    150                 bool needs_signal = false;
    151 
    152                 CHECKED( pthread_mutex_lock(&lock) );
    153                         if(val < 1) {
    154                                 val += 1;
    155                                 pthread_cond_signal(&cond);
    156                                 needs_signal = true;
    157                         }
    158                 CHECKED( pthread_mutex_unlock(&lock) );
    159 
    160                 return needs_signal;
    161         }
    162 
    163         #undef CHECKED
    164 
    165         struct $thread;
    166         extern void park( void );
    167         extern void unpark( struct $thread * this );
    168         static inline struct $thread * active_thread ();
    169 
    170         // Semaphore which only supports a single thread
    171         struct single_sem {
    172                 struct $thread * volatile ptr;
    173         };
    174 
    175         static inline {
    176                 void  ?{}(single_sem & this) {
    177                         this.ptr = 0p;
    178                 }
    179 
    180                 void ^?{}(single_sem &) {}
    181 
    182                 bool wait(single_sem & this) {
    183                         for() {
    184                                 struct $thread * expected = this.ptr;
    185                                 if(expected == 1p) {
    186                                         if(__atomic_compare_exchange_n(&this.ptr, &expected, 0p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
    187                                                 return false;
    188                                         }
    189                                 }
    190                                 else {
    191                                         /* paranoid */ verify( expected == 0p );
    192                                         if(__atomic_compare_exchange_n(&this.ptr, &expected, active_thread(), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
    193                                                 park();
    194                                                 return true;
    195                                         }
    196                                 }
    197 
    198                         }
    199                 }
    200 
    201                 bool post(single_sem & this) {
    202                         for() {
    203                                 struct $thread * expected = this.ptr;
    204                                 if(expected == 1p) return false;
    205                                 if(expected == 0p) {
    206                                         if(__atomic_compare_exchange_n(&this.ptr, &expected, 1p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
    207                                                 return false;
    208                                         }
    209                                 }
    210                                 else {
    211                                         if(__atomic_compare_exchange_n(&this.ptr, &expected, 0p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
    212                                                 unpark( expected );
    213                                                 return true;
    214                                         }
    215                                 }
    216                         }
    217                 }
    218         }
    219 
    220         // Synchronozation primitive which only supports a single thread and one post
    221         // Similar to a binary semaphore with a 'one shot' semantic
    222         // is expected to be discarded after each party call their side
    223         struct oneshot {
    224                 // Internal state :
    225                 //     0p     : is initial state (wait will block)
    226                 //     1p     : fulfilled (wait won't block)
    227                 // any thread : a thread is currently waiting
    228                 struct $thread * volatile ptr;
    229         };
    230 
    231         static inline {
    232                 void  ?{}(oneshot & this) {
    233                         this.ptr = 0p;
    234                 }
    235 
    236                 void ^?{}(oneshot &) {}
    237 
    238                 // Wait for the post, return immidiately if it already happened.
    239                 // return true if the thread was parked
    240                 bool wait(oneshot & this) {
    241                         for() {
    242                                 struct $thread * expected = this.ptr;
    243                                 if(expected == 1p) return false;
    244                                 /* paranoid */ verify( expected == 0p );
    245                                 if(__atomic_compare_exchange_n(&this.ptr, &expected, active_thread(), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
    246                                         park();
    247                                         /* paranoid */ verify( this.ptr == 1p );
    248                                         return true;
    249                                 }
    250                         }
    251                 }
    252 
    253                 // Mark as fulfilled, wake thread if needed
    254                 // return true if a thread was unparked
    255                 bool post(oneshot & this) {
    256                         struct $thread * got = __atomic_exchange_n( &this.ptr, 1p, __ATOMIC_SEQ_CST);
    257                         if( got == 0p ) return false;
    258                         unpark( got );
    259                         return true;
    260                 }
    261         }
    262 
    263         // base types for future to build upon
    264         // It is based on the 'oneshot' type to allow multiple futures
    265         // to block on the same instance, permitting users to block a single
    266         // thread on "any of" [a given set of] futures.
    267         // does not support multiple threads waiting on the same future
    268         struct future_t {
    269                 // Internal state :
    270                 //     0p      : is initial state (wait will block)
    271                 //     1p      : fulfilled (wait won't block)
    272                 //     2p      : in progress ()
    273                 //     3p      : abandoned, server should delete
    274                 // any oneshot : a context has been setup to wait, a thread could wait on it
    275                 struct oneshot * volatile ptr;
    276         };
    277 
    278         static inline {
    279                 void  ?{}(future_t & this) {
    280                         this.ptr = 0p;
    281                 }
    282 
    283                 void ^?{}(future_t &) {}
    284 
    285                 void reset(future_t & this) {
    286                         // needs to be in 0p or 1p
    287                         __atomic_exchange_n( &this.ptr, 0p, __ATOMIC_SEQ_CST);
    288                 }
    289 
    290                 // check if the future is available
    291                 bool available( future_t & this ) {
    292                         return this.ptr == 1p;
    293                 }
    294 
    295                 // Prepare the future to be waited on
    296                 // intented to be use by wait, wait_any, waitfor, etc. rather than used directly
    297                 bool setup( future_t & this, oneshot & wait_ctx ) {
    298                         /* paranoid */ verify( wait_ctx.ptr == 0p );
    299                         // The future needs to set the wait context
    300                         for() {
    301                                 struct oneshot * expected = this.ptr;
    302                                 // Is the future already fulfilled?
    303                                 if(expected == 1p) return false; // Yes, just return false (didn't block)
    304 
    305                                 // The future is not fulfilled, try to setup the wait context
    306                                 /* paranoid */ verify( expected == 0p );
    307                                 if(__atomic_compare_exchange_n(&this.ptr, &expected, &wait_ctx, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
    308                                         return true;
    309                                 }
    310                         }
    311                 }
    312 
    313                 // Stop waiting on a future
    314                 // When multiple futures are waited for together in "any of" pattern
    315                 // futures that weren't fulfilled before the thread woke up
    316                 // should retract the wait ctx
    317                 // intented to be use by wait, wait_any, waitfor, etc. rather than used directly
    318                 void retract( future_t & this, oneshot & wait_ctx ) {
    319                         // Remove the wait context
    320                         struct oneshot * got = __atomic_exchange_n( &this.ptr, 0p, __ATOMIC_SEQ_CST);
    321 
    322                         // got == 0p: future was never actually setup, just return
    323                         if( got == 0p ) return;
    324 
    325                         // got == wait_ctx: since fulfil does an atomic_swap,
    326                         // if we got back the original then no one else saw context
    327                         // It is safe to delete (which could happen after the return)
    328                         if( got == &wait_ctx ) return;
    329 
    330                         // got == 1p: the future is ready and the context was fully consumed
    331                         // the server won't use the pointer again
    332                         // It is safe to delete (which could happen after the return)
    333                         if( got == 1p ) return;
    334 
    335                         // got == 2p: the future is ready but the context hasn't fully been consumed
    336                         // spin until it is safe to move on
    337                         if( got == 2p ) {
    338                                 while( this.ptr != 1p ) Pause();
    339                                 return;
    340                         }
    341 
    342                         // got == any thing else, something wen't wrong here, abort
    343                         abort("Future in unexpected state");
    344                 }
    345 
    346                 // Mark the future as abandoned, meaning it will be deleted by the server
    347                 bool abandon( future_t & this ) {
    348                         /* paranoid */ verify( this.ptr != 3p );
    349 
    350                         // Mark the future as abandonned
    351                         struct oneshot * got = __atomic_exchange_n( &this.ptr, 3p, __ATOMIC_SEQ_CST);
    352 
    353                         // If the future isn't already fulfilled, let the server delete it
    354                         if( got == 0p ) return false;
    355 
    356                         // got == 2p: the future is ready but the context hasn't fully been consumed
    357                         // spin until it is safe to move on
    358                         if( got == 2p ) {
    359                                 while( this.ptr != 1p ) Pause();
    360                                 got = 1p;
    361                         }
    362 
    363                         // The future is completed delete it now
    364                         /* paranoid */ verify( this.ptr != 1p );
    365                         free( &this );
    366                         return true;
    367                 }
    368 
    369                 // from the server side, mark the future as fulfilled
    370                 // delete it if needed
    371                 bool fulfil( future_t & this ) {
    372                         for() {
    373                                 struct oneshot * expected = this.ptr;
    374                                 // was this abandoned?
    375                                 #if defined(__GNUC__) && __GNUC__ >= 7
    376                                         #pragma GCC diagnostic push
    377                                         #pragma GCC diagnostic ignored "-Wfree-nonheap-object"
    378                                 #endif
    379                                         if( expected == 3p ) { free( &this ); return false; }
    380                                 #if defined(__GNUC__) && __GNUC__ >= 7
    381                                         #pragma GCC diagnostic pop
    382                                 #endif
    383 
    384                                 /* paranoid */ verify( expected != 1p ); // Future is already fulfilled, should not happen
    385                                 /* paranoid */ verify( expected != 2p ); // Future is bein fulfilled by someone else, this is even less supported then the previous case.
    386 
    387                                 // If there is a wait context, we need to consume it and mark it as consumed after
    388                                 // If there is no context then we can skip the in progress phase
    389                                 struct oneshot * want = expected == 0p ? 1p : 2p;
    390                                 if(__atomic_compare_exchange_n(&this.ptr, &expected, want, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
    391                                         if( expected == 0p ) { /* paranoid */ verify( this.ptr == 1p); return false; }
    392                                         bool ret = post( *expected );
    393                                         __atomic_store_n( &this.ptr, 1p, __ATOMIC_SEQ_CST);
    394                                         return ret;
    395                                 }
    396                         }
    397 
    398                 }
    399 
    400                 // Wait for the future to be fulfilled
    401                 bool wait( future_t & this ) {
    402                         oneshot temp;
    403                         if( !setup(this, temp) ) return false;
    404 
    405                         // Wait context is setup, just wait on it
    406                         bool ret = wait( temp );
    407 
    408                         // Wait for the future to tru
    409                         while( this.ptr == 2p ) Pause();
    410                         // Make sure the state makes sense
    411                         // Should be fulfilled, could be in progress but it's out of date if so
    412                         // since if that is the case, the oneshot was fulfilled (unparking this thread)
    413                         // and the oneshot should not be needed any more
    414                         __attribute__((unused)) struct oneshot * was = this.ptr;
    415                         /* paranoid */ verifyf( was == 1p, "Expected this.ptr to be 1p, was %p\n", was );
    416 
    417                         // Mark the future as fulfilled, to be consistent
    418                         // with potential calls to avail
    419                         // this.ptr = 1p;
    420                         return ret;
    421                 }
    422         }
    42394#endif
  • TabularUnified libcfa/src/bits/queue.hfa

    r467c8b7 rc08c3cf  
    99// instead of being null.
    1010
    11 forall( dtype T | { T *& Next ( T * ); } ) {
     11forall( T & | { T *& Next ( T * ); } ) {
    1212        struct Queue {
    1313                inline Collection;                                                              // Plan 9 inheritance
     
    151151} // distribution
    152152
    153 forall( dtype T | { T *& Next ( T * ); } ) {
     153forall( T & | { T *& Next ( T * ); } ) {
    154154        struct QueueIter {
    155155                inline ColIter;                                                                 // Plan 9 inheritance
  • TabularUnified libcfa/src/bits/sequence.hfa

    r467c8b7 rc08c3cf  
    2929
    3030        // // wrappers to make Collection have T
    31         // forall( dtype T ) {
     31        // forall( T & ) {
    3232        //      T *& Back( T * n ) {
    3333        //              return (T *)Back( (Seqable *)n );
     
    4343// and the back field of the last node points at the first node (circular).
    4444
    45 forall( dtype T | { T *& Back ( T * ); T *& Next ( T * ); } ) {
     45forall( T & | { T *& Back ( T * ); T *& Next ( T * ); } ) {
    4646        struct Sequence {
    4747                inline Collection;                                                              // Plan 9 inheritance
     
    231231} // distribution
    232232
    233 forall( dtype T | { T *& Back ( T * ); T *& Next ( T * ); } ) {
     233forall( T & | { T *& Back ( T * ); T *& Next ( T * ); } ) {
    234234        // SeqIter(T) is used to iterate over a Sequence(T) in head-to-tail order.
    235235        struct SeqIter {
  • TabularUnified libcfa/src/bits/stack.hfa

    r467c8b7 rc08c3cf  
    99// instead of being null.
    1010
    11 forall( dtype T | { T *& Next ( T * ); } ) {
     11forall( T & | { T *& Next ( T * ); } ) {
    1212        struct Stack {
    1313                inline Collection;                                                              // Plan 9 inheritance
     
    6767// order returned by drop().
    6868
    69 forall( dtype T | { T *& Next ( T * ); } ) {
     69forall( T & | { T *& Next ( T * ); } ) {
    7070        struct StackIter {
    7171                inline ColIter;                                                                 // Plan 9 inheritance
Note: See TracChangeset for help on using the changeset viewer.