Changeset 6d2af204 for libcfa


Ignore:
Timestamp:
Feb 5, 2023, 11:42:15 AM (3 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, ast-experimental, master
Children:
8fa77eb
Parents:
9ef5516 (diff), 35d1de5 (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:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
libcfa
Files:
16 edited

Legend:

Unmodified
Added
Removed
  • libcfa/prelude/builtins.c

    r9ef5516 r6d2af204  
    1010// Created On       : Fri Jul 21 16:21:03 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Aug 14 08:45:54 2021
    13 // Update Count     : 133
     12// Last Modified On : Thu Feb  2 11:33:56 2023
     13// Update Count     : 135
    1414//
    1515
     
    6464static inline void ^?{}(generator$ &) {}
    6565
    66 trait is_generator(T &) {
     66forall( T & )
     67trait is_generator {
    6768      void main(T & this);
    6869      generator$ * get_generator(T & this);
  • libcfa/prelude/prelude-gen.cc

    r9ef5516 r6d2af204  
    1010// Created On       : Sat Feb 16 08:44:58 2019
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Apr  2 17:18:24 2019
    13 // Update Count     : 37
     12// Last Modified On : Thu Feb  2 11:40:01 2023
     13// Update Count     : 38
    1414//
    1515
     
    159159int main() {
    160160        cout << "# 2 \"prelude.cfa\"  // needed for error messages from this file" << endl;
    161         cout << "trait sized(T &) {};" << endl;
     161        cout << "forall( T & ) trait sized {};" << endl;
    162162
    163163        cout << "//////////////////////////" << endl;
  • libcfa/src/bits/containers.hfa

    r9ef5516 r6d2af204  
    1010// Created On       : Tue Oct 31 16:38:50 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jan 15 07:42:35 2020
    13 // Update Count     : 28
     12// Last Modified On : Thu Feb  2 11:33:08 2023
     13// Update Count     : 29
    1414
    1515#pragma once
     
    6969
    7070#ifdef __cforall
    71         trait is_node(T &) {
     71        forall( T & )
     72        trait is_node {
    7273                T *& get_next( T & );
    7374        };
  • libcfa/src/concurrency/actor.hfa

    r9ef5516 r6d2af204  
     1#pragma once
     2
    13#include <locks.hfa>
    24#include <limits.hfa>
    35#include <list.hfa>
     6#include <kernel.hfa>
    47
    58#ifdef __CFA_DEBUG__
     
    2124// Define if executor is created in a separate cluster
    2225#define __DEFAULT_EXECUTOR_SEPCLUS__ false
     26
     27// when you flip this make sure to recompile compiler and flip the appropriate flag there too in Actors.cpp
     28#define __ALLOC 0
    2329
    2430// forward decls
     
    3844P9_EMBEDDED( request, dlink(request) )
    3945
    40 void ?{}( request & this ) { this.stop = true; } // default ctor makes a sentinel
    41 void ?{}( request & this, actor * receiver, message * msg, __receive_fn fn ) {
     46static inline void ?{}( request & this ) { this.stop = true; } // default ctor makes a sentinel
     47static inline void ?{}( request & this, actor * receiver, message * msg, __receive_fn fn ) {
    4248    this.receiver = receiver;
    4349    this.msg = msg;
     
    4551    this.stop = false;
    4652}
    47 
     53static inline void ?{}( request & this, request & copy ) {
     54    this.receiver = copy.receiver;
     55    this.msg = copy.msg;
     56    this.fn = copy.fn;
     57    this.stop = copy.stop;
     58}
     59
     60// hybrid data structure. Copies until buffer is full and then allocates for intrusive list
     61struct copy_queue {
     62    dlist( request ) list;
     63    #if ! __ALLOC
     64    request * buffer;
     65    size_t count, buffer_size, index;
     66    #endif
     67};
     68static inline void ?{}( copy_queue & this ) {}
     69static inline void ?{}( copy_queue & this, size_t buf_size ) with(this) {
     70    list{};
     71    #if ! __ALLOC
     72    buffer_size = buf_size;
     73    buffer = aalloc( buffer_size );
     74    count = 0;
     75    index = 0;
     76    #endif
     77}
     78static inline void ^?{}( copy_queue & this ) with(this) {
     79    #if ! __ALLOC
     80    adelete(buffer);
     81    #endif
     82}
     83
     84static inline void insert( copy_queue & this, request & elem ) with(this) {
     85    #if ! __ALLOC
     86    if ( count < buffer_size ) { // fast path ( no alloc )
     87        buffer[count]{ elem };
     88        count++;
     89        return;
     90    }
     91    request * new_elem = alloc();
     92    (*new_elem){ elem };
     93    insert_last( list, *new_elem );
     94    #else
     95    insert_last( list, elem );
     96    #endif
     97}
     98
     99// once you start removing you need to remove all elements
     100// it is not supported to call insert() before the list is fully empty
     101// should_delete is an output param
     102static inline request & remove( copy_queue & this, bool & should_delete ) with(this) {
     103    #if ! __ALLOC
     104    if ( count > 0 ) {
     105        count--;
     106        should_delete = false;
     107        size_t old_idx = index;
     108        index = count == 0 ? 0 : index + 1;
     109        return buffer[old_idx];
     110    }
     111    #endif
     112    should_delete = true;
     113    return try_pop_front( list );
     114}
     115
     116static inline bool isEmpty( copy_queue & this ) with(this) {
     117    #if ! __ALLOC
     118    return count == 0 && list`isEmpty;
     119    #else
     120    return list`isEmpty;
     121    #endif
     122}
     123
     124static size_t __buffer_size = 10; // C_TODO: rework this to be passed from executor through ctors (no need for global)
    48125struct work_queue {
    49     futex_mutex mutex_lock;
    50     dlist( request ) input;                                             // unbounded list of work requests
     126    __spinlock_t mutex_lock;
     127    copy_queue owned_queue;
     128    copy_queue * c_queue; // C_TODO: try putting this on the stack with ptr juggling
     129
    51130}; // work_queue
    52 void ?{}( work_queue & this ) with(this) { input{}; mutex_lock{}; }
    53 
    54 void insert( work_queue & this, request & elem ) with(this) {
    55     lock( mutex_lock );
    56     insert_last( input, elem );
     131static inline void ?{}( work_queue & this ) with(this) {
     132    // c_queue = alloc();
     133    // (*c_queue){ __buffer_size };
     134    owned_queue{ __buffer_size };
     135    c_queue = &owned_queue;
     136}
     137// static inline void ^?{}( work_queue & this ) with(this) { delete( c_queue ); }
     138
     139static inline void insert( work_queue & this, request & elem ) with(this) {
     140    lock( mutex_lock __cfaabi_dbg_ctx2 );
     141    insert( *c_queue, elem );
    57142    unlock( mutex_lock );
    58143} // insert
    59144
    60 void transfer( work_queue & this, dlist(request) & transferTo ) with(this) {
    61     lock( mutex_lock );
    62 
    63     //C_TODO CHANGE
    64     // transferTo->transfer( input );              // transfer input to output
    65 
    66     // this is awfully inefficient but Ill use it until transfer is implemented
    67     request * r;
    68     while ( ! input`isEmpty ) {
    69         r = &try_pop_front( input );
    70         if ( r ) insert_last( transferTo, *r );
    71     }
    72 
    73     // transfer( input, transferTo );
    74 
     145static inline void transfer( work_queue & this, copy_queue ** transfer_to ) with(this) {
     146    lock( mutex_lock __cfaabi_dbg_ctx2 );
     147    // swap copy queue ptrs
     148    copy_queue * temp = *transfer_to;
     149    *transfer_to = c_queue;
     150    c_queue = temp;
    75151    unlock( mutex_lock );
    76152} // transfer
    77153
    78154thread worker {
     155    copy_queue owned_queue;
    79156    work_queue * request_queues;
    80     dlist( request ) current_queue;
     157    copy_queue * current_queue;
    81158        request & req;
    82159    unsigned int start, range;
     
    86163    ((thread &)this){ clu };
    87164    this.request_queues = request_queues;
    88     this.current_queue{};
     165    // this.current_queue = alloc();
     166    // (*this.current_queue){ __buffer_size };
     167    this.owned_queue{ __buffer_size };
     168    this.current_queue = &this.owned_queue;
    89169    this.start = start;
    90170    this.range = range;
    91171}
     172// static inline void ^?{}( worker & mutex this ) with(this) { delete( current_queue ); }
    92173
    93174struct executor {
     
    100181}; // executor
    101182
    102 static inline void ?{}( executor & this, unsigned int nprocessors, unsigned int nworkers, unsigned int nrqueues, bool seperate_clus ) with(this) {
     183static inline void ?{}( executor & this, unsigned int nprocessors, unsigned int nworkers, unsigned int nrqueues, bool seperate_clus, size_t buf_size ) with(this) {
    103184    if ( nrqueues < nworkers ) abort( "nrqueues needs to be >= nworkers\n" );
     185    __buffer_size = buf_size;
    104186    this.nprocessors = nprocessors;
    105187    this.nworkers = nworkers;
     
    127209    } // for
    128210}
    129 
     211static inline void ?{}( executor & this, unsigned int nprocessors, unsigned int nworkers, unsigned int nrqueues, bool seperate_clus ) { this{ nprocessors, nworkers, nrqueues, seperate_clus, __buffer_size }; }
    130212static inline void ?{}( executor & this, unsigned int nprocessors, unsigned int nworkers, unsigned int nrqueues ) { this{ nprocessors, nworkers, nrqueues, __DEFAULT_EXECUTOR_SEPCLUS__ }; }
    131213static inline void ?{}( executor & this, unsigned int nprocessors, unsigned int nworkers ) { this{ nprocessors, nworkers, __DEFAULT_EXECUTOR_RQUEUES__ }; }
     
    147229    } // for
    148230
    149     delete( workers );
    150     delete( request_queues );
    151     delete( processors );
     231    adelete( workers );
     232    adelete( request_queues );
     233    adelete( processors );
    152234    if ( seperate_clus ) delete( cluster );
    153235}
     
    170252};
    171253
    172 void ?{}( actor & this ) {
     254static inline void ?{}( actor & this ) {
    173255    // Once an actor is allocated it must be sent a message or the actor system cannot stop. Hence, its receive
    174256    // member must be called to end it
     
    178260    __atomic_fetch_add( &__num_actors_, 1, __ATOMIC_SEQ_CST );
    179261}
    180 void ^?{}( actor & this ) {}
     262static inline void ^?{}( actor & this ) {}
    181263
    182264static inline void check_actor( actor & this ) {
     
    204286};
    205287
    206 void ?{}( message & this ) { this.allocation_ = Nodelete; }
    207 void ?{}( message & this, Allocation allocation ) { this.allocation_ = allocation; }
    208 void ^?{}( message & this ) {}
     288static inline void ?{}( message & this ) { this.allocation_ = Nodelete; }
     289static inline void ?{}( message & this, Allocation allocation ) { this.allocation_ = allocation; }
     290static inline void ^?{}( message & this ) {}
    209291
    210292static inline void check_message( message & this ) {
     
    217299}
    218300
    219 void deliver_request( request & this ) {
     301static inline void deliver_request( request & this ) {
    220302    Allocation actor_allocation = this.fn( *this.receiver, *this.msg );
    221303    this.receiver->allocation_ = actor_allocation;
     
    225307
    226308void main( worker & this ) with(this) {
     309    bool should_delete;
    227310    Exit:
    228311    for ( unsigned int i = 0;; i = (i + 1) % range ) { // cycle through set of request buffers
    229         transfer( request_queues[i + start], current_queue );
    230         while ( ! current_queue`isEmpty ) {
    231             &req = &try_pop_front( current_queue );
     312        // C_TODO: potentially check queue count instead of immediately trying to transfer
     313        transfer( request_queues[i + start], &current_queue );
     314        while ( ! isEmpty( *current_queue ) ) {
     315            &req = &remove( *current_queue, should_delete );
    232316            if ( !&req ) continue; // possibly add some work stealing/idle sleep here
    233317            if ( req.stop ) break Exit;
    234318            deliver_request( req );
    235319
    236             delete( &req );
     320            if ( should_delete ) delete( &req );
    237321        } // while
    238322    } // for
     
    250334    __actor_executor_thd = active_thread();
    251335    __actor_executor_ = alloc();
    252     (*__actor_executor_){ 0, num_thds, num_thds * 16 };
     336    (*__actor_executor_){ 0, num_thds, num_thds == 1 ? 1 : num_thds * 16 };
    253337}
    254338
  • libcfa/src/concurrency/coroutine.hfa

    r9ef5516 r6d2af204  
    1010// Created On       : Mon Nov 28 12:27:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jan  6 16:33:16 2022
    13 // Update Count     : 12
     12// Last Modified On : Thu Feb  2 11:31:42 2023
     13// Update Count     : 13
    1414//
    1515
     
    3838// Anything that implements this trait can be resumed.
    3939// Anything that is resumed is a coroutine.
    40 trait is_coroutine(T & | IS_RESUMPTION_EXCEPTION(CoroutineCancelled(T))) {
     40forall( T & | IS_RESUMPTION_EXCEPTION(CoroutineCancelled(T)) )
     41trait is_coroutine {
    4142        void main(T & this);
    4243        coroutine$ * get_coroutine(T & this);
  • libcfa/src/concurrency/locks.hfa

    r9ef5516 r6d2af204  
    640640//-----------------------------------------------------------------------------
    641641// is_blocking_lock
    642 trait is_blocking_lock(L & | sized(L)) {
     642forall( L & | sized(L) )
     643trait is_blocking_lock {
    643644        // For synchronization locks to use when acquiring
    644645        void on_notify( L &, struct thread$ * );
  • libcfa/src/concurrency/monitor.hfa

    r9ef5516 r6d2af204  
    1010// Created On       : Thd Feb 23 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Dec  4 07:55:32 2019
    13 // Update Count     : 11
     12// Last Modified On : Thu Feb  2 11:29:21 2023
     13// Update Count     : 12
    1414//
    1515
     
    2222#include "stdlib.hfa"
    2323
    24 trait is_monitor(T &) {
     24forall( T & )
     25trait is_monitor {
    2526        monitor$ * get_monitor( T & );
    2627        void ^?{}( T & mutex );
  • libcfa/src/concurrency/mutex.hfa

    r9ef5516 r6d2af204  
    1212// Created On       : Fri May 25 01:24:09 2018
    1313// Last Modified By : Peter A. Buhr
    14 // Last Modified On : Wed Dec  4 09:16:53 2019
    15 // Update Count     : 1
     14// Last Modified On : Thu Feb  2 11:46:08 2023
     15// Update Count     : 2
    1616//
    1717
     
    7070void unlock(recursive_mutex_lock & this) __attribute__((deprecated("use concurrency/locks.hfa instead")));
    7171
    72 trait is_lock(L & | sized(L)) {
     72forall( L & | sized(L) )
     73trait is_lock {
    7374        void lock  (L &);
    7475        void unlock(L &);
  • libcfa/src/concurrency/thread.hfa

    r9ef5516 r6d2af204  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Nov 22 22:18:34 2022
    13 // Update Count     : 35
     12// Last Modified On : Thu Feb  2 11:27:59 2023
     13// Update Count     : 37
    1414//
    1515
     
    2727//-----------------------------------------------------------------------------
    2828// thread trait
    29 trait is_thread(T &) {
     29forall( T & )
     30trait is_thread {
    3031        void ^?{}(T& mutex this);
    3132        void main(T& this);
  • libcfa/src/containers/list.hfa

    r9ef5516 r6d2af204  
    99// Author           : Michael Brooks
    1010// Created On       : Wed Apr 22 18:00:00 2020
    11 // Last Modified By : Michael Brooks
    12 // Last Modified On : Wed Apr 22 18:00:00 2020
    13 // Update Count     : 1
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Thu Feb  2 11:32:26 2023
     13// Update Count     : 2
    1414//
    1515
     
    2323};
    2424
    25 trait embedded( tOuter &, tMid &, tInner & ) {
     25forall( tOuter &, tMid &, tInner & )
     26trait embedded {
    2627    tytagref( tMid, tInner ) ?`inner( tOuter & );
    2728};
  • libcfa/src/containers/vector.hfa

    r9ef5516 r6d2af204  
    1010// Created On       : Tue Jul  5 18:00:07 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jun 17 11:02:46 2020
    13 // Update Count     : 4
     12// Last Modified On : Thu Feb  2 11:41:24 2023
     13// Update Count     : 5
    1414//
    1515
     
    5050//------------------------------------------------------------------------------
    5151//Declaration
    52 trait allocator_c(T, allocator_t)
    53 {
     52forall( T, allocator_t )
     53trait allocator_c {
    5454        void realloc_storage(allocator_t*, size_t);
    5555        T* data(allocator_t*);
  • libcfa/src/exception.h

    r9ef5516 r6d2af204  
    99// Author           : Andrew Beach
    1010// Created On       : Mon Jun 26 15:11:00 2017
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Thr Apr  8 15:20:00 2021
    13 // Update Count     : 12
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Thu Feb  2 11:20:19 2023
     13// Update Count     : 13
    1414//
    1515
     
    101101// implemented in the .c file either so they all have to be inline.
    102102
    103 trait is_exception(exceptT &, virtualT &) {
     103forall( exceptT &, virtualT & )
     104trait is_exception {
    104105        /* The first field must be a pointer to a virtual table.
    105106         * That virtual table must be a decendent of the base exception virtual table.
     
    109110};
    110111
    111 trait is_termination_exception(exceptT &, virtualT & | is_exception(exceptT, virtualT)) {
     112forall( exceptT &, virtualT & | is_exception(exceptT, virtualT) )
     113trait is_termination_exception {
    112114        void defaultTerminationHandler(exceptT &);
    113115};
    114116
    115 trait is_resumption_exception(exceptT &, virtualT & | is_exception(exceptT, virtualT)) {
     117forall( exceptT &, virtualT & | is_exception(exceptT, virtualT) )
     118trait is_resumption_exception {
    116119        void defaultResumptionHandler(exceptT &);
    117120};
  • libcfa/src/iostream.hfa

    r9ef5516 r6d2af204  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Oct 10 10:02:07 2021
    13 // Update Count     : 407
     12// Last Modified On : Thu Feb  2 11:25:39 2023
     13// Update Count     : 410
    1414//
    1515
     
    2222
    2323
    24 trait basic_ostream( ostype & ) {
     24forall( ostype & )
     25trait basic_ostream {
    2526        // private
    2627        bool sepPrt$( ostype & );                                                       // get separator state (on/off)
     
    5152}; // basic_ostream
    5253       
    53 trait ostream( ostype & | basic_ostream( ostype ) ) {
     54forall( ostype & | basic_ostream( ostype ) )
     55trait ostream {
    5456        bool fail( ostype & );                                                          // operation failed?
    5557        void clear( ostype & );
     
    6062}; // ostream
    6163
    62 // trait writeable( T ) {
     64// forall( T )
     65// trait writeable {
    6366//      forall( ostype & | ostream( ostype ) ) ostype & ?|?( ostype &, T );
    6467// }; // writeable
    6568
    66 trait writeable( T, ostype & | ostream( ostype ) ) {
     69forall( T, ostype & | ostream( ostype ) )
     70        trait writeable {
    6771        ostype & ?|?( ostype &, T );
    6872}; // writeable
     
    290294
    291295
    292 trait basic_istream( istype & ) {
     296forall( istype & )
     297trait basic_istream {
    293298        // private
    294299        bool getANL$( istype & );                                                       // get scan newline (on/off)
     
    302307}; // basic_istream
    303308
    304 trait istream( istype & | basic_istream( istype ) ) {
     309forall( istype & | basic_istream( istype ) )
     310trait istream {
    305311        bool fail( istype & );
    306312        void clear( istype & );
     
    310316}; // istream
    311317
    312 trait readable( T ) {
     318forall( T )
     319trait readable {
    313320        forall( istype & | istream( istype ) ) istype & ?|?( istype &, T );
    314321}; // readable
  • libcfa/src/iterator.hfa

    r9ef5516 r6d2af204  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul  7 08:37:25 2017
    13 // Update Count     : 10
     12// Last Modified On : Thu Feb  2 11:21:50 2023
     13// Update Count     : 11
    1414//
    1515
     
    1717
    1818// An iterator can be used to traverse a data structure.
    19 trait iterator( iterator_type, elt_type ) {
     19forall( iterator_type, elt_type )
     20trait iterator {
    2021        // point to the next element
    2122//      iterator_type ?++( iterator_type & );
     
    3132};
    3233
    33 trait iterator_for( iterator_type, collection_type, elt_type | iterator( iterator_type, elt_type ) ) {
     34forall( iterator_type, collection_type, elt_type | iterator( iterator_type, elt_type ) )
     35        trait iterator_for {
    3436//      [ iterator_type begin, iterator_type end ] get_iterators( collection_type );
    3537        iterator_type begin( collection_type );
  • libcfa/src/math.trait.hfa

    r9ef5516 r6d2af204  
    1010// Created On       : Fri Jul 16 15:40:52 2021
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jul 20 17:47:19 2021
    13 // Update Count     : 19
     12// Last Modified On : Thu Feb  2 11:36:56 2023
     13// Update Count     : 20
    1414//
    1515
    1616#pragma once
    1717
    18 trait Not( U ) {
     18forall( U )
     19trait Not {
    1920        void ?{}( U &, zero_t );
    2021        int !?( U );
    2122}; // Not
    2223
    23 trait Equality( T | Not( T ) ) {
     24forall( T | Not( T ) )
     25trait Equality {
    2426        int ?==?( T, T );
    2527        int ?!=?( T, T );
    2628}; // Equality
    2729
    28 trait Relational( U | Equality( U ) ) {
     30forall( U | Equality( U ) )
     31trait Relational {
    2932        int ?<?( U, U );
    3033        int ?<=?( U, U );
     
    3336}; // Relational
    3437
    35 trait Signed( T ) {
     38forall ( T )
     39trait Signed {
    3640        T +?( T );
    3741        T -?( T );
     
    3943}; // Signed
    4044
    41 trait Additive( U | Signed( U ) ) {
     45forall( U | Signed( U ) )
     46trait Additive {
    4247        U ?+?( U, U );
    4348        U ?-?( U, U );
     
    4651}; // Additive
    4752
    48 trait Incdec( T | Additive( T ) ) {
     53forall( T | Additive( T ) )
     54trait Incdec {
    4955        void ?{}( T &, one_t );
    5056        // T ?++( T & );
     
    5460}; // Incdec
    5561
    56 trait Multiplicative( U | Incdec( U ) ) {
     62forall( U | Incdec( U ) )
     63trait Multiplicative {
    5764        U ?*?( U, U );
    5865        U ?/?( U, U );
     
    6168}; // Multiplicative
    6269
    63 trait Arithmetic( T | Relational( T ) | Multiplicative( T ) ) {
     70forall( T | Relational( T ) | Multiplicative( T ) )
     71trait Arithmetic {
    6472}; // Arithmetic
    6573
  • libcfa/src/stdlib.hfa

    r9ef5516 r6d2af204  
    1010// Created On       : Thu Jan 28 17:12:35 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Dec 11 18:25:53 2022
    13 // Update Count     : 765
     12// Last Modified On : Thu Feb  2 11:30:04 2023
     13// Update Count     : 766
    1414//
    1515
     
    404404//   calls( sprng );
    405405
    406 trait basic_prng( PRNG &, R ) {
     406forall( PRNG &, R )
     407trait basic_prng {
    407408        void set_seed( PRNG & prng, R seed );                           // set seed
    408409        R get_seed( PRNG & prng );                                                      // get seed
Note: See TracChangeset for help on using the changeset viewer.