Changeset 8a930c03 for libcfa/src
- Timestamp:
- Jun 12, 2023, 12:05:58 PM (12 months ago)
- Branches:
- master
- Children:
- fec8bd1
- Parents:
- 2b78949 (diff), 38e266c (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. - Location:
- libcfa/src
- Files:
-
- 1 added
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/Makefile.am
r2b78949 r8a930c03 11 11 ## Created On : Sun May 31 08:54:01 2015 12 12 ## Last Modified By : Peter A. Buhr 13 ## Last Modified On : Fri Jul 16 16:00:40 202114 ## Update Count : 25 513 ## Last Modified On : Thu May 25 15:20:04 2023 14 ## Update Count : 259 15 15 ############################################################################### 16 16 … … 59 59 bits/queue.hfa \ 60 60 bits/sequence.hfa \ 61 concurrency/atomic.hfa \ 61 62 concurrency/iofwd.hfa \ 62 63 concurrency/barrier.hfa \ … … 115 116 concurrency/kernel/fwd.hfa \ 116 117 concurrency/mutex_stmt.hfa \ 117 118 118 concurrency/channel.hfa \ 119 concurrency/actor.hfa 119 120 120 121 inst_thread_headers_src = \ … … 127 128 concurrency/monitor.hfa \ 128 129 concurrency/mutex.hfa \ 129 130 concurrency/select.hfa \ 130 131 concurrency/thread.hfa 131 132 -
libcfa/src/bits/weakso_locks.cfa
r2b78949 r8a930c03 30 30 bool register_select( blocking_lock & this, select_node & node ) { return false; } 31 31 bool unregister_select( blocking_lock & this, select_node & node ) { return false; } 32 bool on_selected( blocking_lock & this, select_node & node ) { return true;}32 void on_selected( blocking_lock & this, select_node & node ) {} 33 33 -
libcfa/src/bits/weakso_locks.hfa
r2b78949 r8a930c03 62 62 bool register_select( blocking_lock & this, select_node & node ) OPTIONAL_THREAD; 63 63 bool unregister_select( blocking_lock & this, select_node & node ) OPTIONAL_THREAD; 64 boolon_selected( blocking_lock & this, select_node & node ) OPTIONAL_THREAD;64 void on_selected( blocking_lock & this, select_node & node ) OPTIONAL_THREAD; 65 65 66 66 //---------- … … 80 80 static inline bool register_select( multiple_acquisition_lock & this, select_node & node ) { return register_select( (blocking_lock &)this, node ); } 81 81 static inline bool unregister_select( multiple_acquisition_lock & this, select_node & node ) { return unregister_select( (blocking_lock &)this, node ); } 82 static inline bool on_selected( multiple_acquisition_lock & this, select_node & node ) { returnon_selected( (blocking_lock &)this, node ); }82 static inline void on_selected( multiple_acquisition_lock & this, select_node & node ) { on_selected( (blocking_lock &)this, node ); } -
libcfa/src/concurrency/actor.hfa
r2b78949 r8a930c03 13 13 #endif // CFA_DEBUG 14 14 15 #define DEBUG_ABORT( cond, string ) CFA_DEBUG( if ( cond ) abort( string ) ) 16 15 17 // Define the default number of processors created in the executor. Must be greater than 0. 16 18 #define __DEFAULT_EXECUTOR_PROCESSORS__ 2 … … 42 44 struct executor; 43 45 44 enum Allocation { Nodelete, Delete, Destroy, Finished }; // allocation status45 46 typedef Allocation (*__receive_fn)(actor &, message &);46 enum allocation { Nodelete, Delete, Destroy, Finished }; // allocation status 47 48 typedef allocation (*__receive_fn)(actor &, message &); 47 49 struct request { 48 50 actor * receiver; … … 393 395 struct actor { 394 396 size_t ticket; // executor-queue handle 395 Allocation allocation_; // allocation action397 allocation allocation_; // allocation action 396 398 inline virtual_dtor; 397 399 }; … … 400 402 // Once an actor is allocated it must be sent a message or the actor system cannot stop. Hence, its receive 401 403 // member must be called to end it 402 verifyf( __actor_executor_, "Creating actor before calling start_actor_system() can cause undefined behaviour.\n" );404 DEBUG_ABORT( __actor_executor_ == 0p, "Creating actor before calling start_actor_system() can cause undefined behaviour.\n" ); 403 405 allocation_ = Nodelete; 404 406 ticket = __get_next_ticket( *__actor_executor_ ); … … 430 432 431 433 struct message { 432 Allocation allocation_; // allocation action434 allocation allocation_; // allocation action 433 435 inline virtual_dtor; 434 436 }; … … 437 439 this.allocation_ = Nodelete; 438 440 } 439 static inline void ?{}( message & this, Allocation allocation) {440 memcpy( &this.allocation_, &alloc ation, sizeof(allocation) ); // optimization to elide ctor441 verifyf( this.allocation_ != Finished, "The Finished Allocation status is not supported for message types.\n");441 static inline void ?{}( message & this, allocation alloc ) { 442 memcpy( &this.allocation_, &alloc, sizeof(allocation) ); // optimization to elide ctor 443 DEBUG_ABORT( this.allocation_ == Finished, "The Finished allocation status is not supported for message types.\n" ); 442 444 } 443 445 static inline void ^?{}( message & this ) with(this) { … … 453 455 } // switch 454 456 } 455 static inline void set_allocation( message & this, Allocation state ) {457 static inline void set_allocation( message & this, allocation state ) { 456 458 this.allocation_ = state; 457 459 } 458 460 459 461 static inline void deliver_request( request & this ) { 462 DEBUG_ABORT( this.receiver->ticket == (unsigned long int)MAX, "Attempted to send message to deleted/dead actor\n" ); 460 463 this.receiver->allocation_ = this.fn( *this.receiver, *this.msg ); 461 464 check_message( *this.msg ); … … 631 634 632 635 static inline void send( actor & this, request & req ) { 633 verifyf( this.ticket != (unsigned long int)MAX, "Attempted to send message to deleted/dead actor\n" );636 DEBUG_ABORT( this.ticket == (unsigned long int)MAX, "Attempted to send message to deleted/dead actor\n" ); 634 637 send( *__actor_executor_, req, this.ticket ); 635 638 } … … 680 683 // assigned at creation to __base_msg_finished to avoid unused message warning 681 684 message __base_msg_finished @= { .allocation_ : Finished }; 682 struct __ DeleteMsg { inline message; } DeleteMsg = __base_msg_finished;683 struct __ DestroyMsg { inline message; } DestroyMsg = __base_msg_finished;684 struct __ FinishedMsg { inline message; } FinishedMsg = __base_msg_finished;685 686 Allocation receive( actor & this, __DeleteMsg& msg ) { return Delete; }687 Allocation receive( actor & this, __DestroyMsg& msg ) { return Destroy; }688 Allocation receive( actor & this, __FinishedMsg& msg ) { return Finished; }689 685 struct __delete_msg_t { inline message; } delete_msg = __base_msg_finished; 686 struct __destroy_msg_t { inline message; } destroy_msg = __base_msg_finished; 687 struct __finished_msg_t { inline message; } finished_msg = __base_msg_finished; 688 689 allocation receive( actor & this, __delete_msg_t & msg ) { return Delete; } 690 allocation receive( actor & this, __destroy_msg_t & msg ) { return Destroy; } 691 allocation receive( actor & this, __finished_msg_t & msg ) { return Finished; } 692 -
libcfa/src/concurrency/channel.hfa
r2b78949 r8a930c03 51 51 vtable(channel_closed) channel_closed_vt; 52 52 53 static inline bool is_insert( channel_closed & e ) { return e.elem != 0p; } 54 static inline bool is_remove( channel_closed & e ) { return e.elem == 0p; } 55 53 56 // #define CHAN_STATS // define this to get channel stats printed in dtor 54 57 … … 341 344 } 342 345 346 // special case of __handle_waituntil_OR, that does some work to avoid starvation/deadlock case 347 static inline bool __handle_pending( dlist( select_node ) & queue, select_node & mine ) { 348 while ( !queue`isEmpty ) { 349 // if node not a special OR case or if we win the special OR case race break 350 if ( !queue`first.clause_status || queue`first.park_counter || __pending_set_other( queue`first, mine, ((unsigned long int)(&(queue`first))) ) ) 351 return true; 352 353 // our node lost the race when toggling in __pending_set_other 354 if ( *mine.clause_status != __SELECT_PENDING ) 355 return false; 356 357 // otherwise we lost the special OR race so discard node 358 try_pop_front( queue ); 359 } 360 return false; 361 } 362 343 363 // type used by select statement to capture a chan read as the selected operation 344 364 struct chan_read { … … 374 394 return false; 375 395 } 376 377 if ( __handle_ waituntil_OR( prods) ) {396 397 if ( __handle_pending( prods, node ) ) { 378 398 __prods_handoff( chan, ret ); 379 399 __make_select_node_sat( node ); // need to to mark SAT now that we know operation is done or else threads could get stuck in __mark_select_node … … 381 401 return true; 382 402 } 383 __make_select_node_unsat( node ); 403 if ( *node.clause_status == __SELECT_PENDING ) 404 __make_select_node_unsat( node ); 384 405 } 385 406 // check if we can complete operation. If so race to establish winner in special OR case … … 423 444 } 424 445 static inline bool unregister_select( chan_read(T) & this, select_node & node ) { return unregister_chan( this.chan, node ); } 425 static inline boolon_selected( chan_read(T) & this, select_node & node ) with(this) {446 static inline void on_selected( chan_read(T) & this, select_node & node ) with(this) { 426 447 if ( node.extra == 0p ) // check if woken up due to closed channel 427 448 __closed_remove( chan, ret ); 428 449 // This is only reachable if not closed or closed exception was handled 429 return true;430 450 } 431 451 … … 464 484 return false; 465 485 } 466 467 if ( __handle_ waituntil_OR( cons) ) {486 487 if ( __handle_pending( cons, node ) ) { 468 488 __cons_handoff( chan, elem ); 469 489 __make_select_node_sat( node ); // need to to mark SAT now that we know operation is done or else threads could get stuck in __mark_select_node … … 471 491 return true; 472 492 } 473 __make_select_node_unsat( node ); 493 if ( *node.clause_status == __SELECT_PENDING ) 494 __make_select_node_unsat( node ); 474 495 } 475 496 // check if we can complete operation. If so race to establish winner in special OR case … … 515 536 static inline bool unregister_select( chan_write(T) & this, select_node & node ) { return unregister_chan( this.chan, node ); } 516 537 517 static inline boolon_selected( chan_write(T) & this, select_node & node ) with(this) {538 static inline void on_selected( chan_write(T) & this, select_node & node ) with(this) { 518 539 if ( node.extra == 0p ) // check if woken up due to closed channel 519 540 __closed_insert( chan, elem ); 520 541 521 542 // This is only reachable if not closed or closed exception was handled 522 return true;523 543 } 524 544 -
libcfa/src/concurrency/future.hfa
r2b78949 r8a930c03 70 70 // check if the future is available 71 71 // currently no mutual exclusion because I can't see when you need this call to be synchronous or protected 72 bool available( future(T) & this ) { return this.state; }72 bool available( future(T) & this ) { return __atomic_load_n( &this.state, __ATOMIC_RELAXED ); } 73 73 74 74 … … 180 180 } 181 181 182 bool on_selected( future(T) & this, select_node & node ) { return true;}182 void on_selected( future(T) & this, select_node & node ) {} 183 183 } 184 184 } 185 185 186 186 //-------------------------------------------------------------------------------------------------------- 187 // These futures below do not support select statements so they may not be as usefulas 'future'187 // These futures below do not support select statements so they may not have as many features as 'future' 188 188 // however the 'single_future' is cheap and cheerful and is most likely more performant than 'future' 189 189 // since it uses raw atomics and no locks -
libcfa/src/concurrency/locks.cfa
r2b78949 r8a930c03 239 239 } 240 240 241 bool on_selected( blocking_lock & this, select_node & node ) { return true;}241 void on_selected( blocking_lock & this, select_node & node ) {} 242 242 243 243 //----------------------------------------------------------------------------- -
libcfa/src/concurrency/locks.hfa
r2b78949 r8a930c03 32 32 #include "select.hfa" 33 33 34 #include <fstream.hfa>35 36 34 // futex headers 37 35 #include <linux/futex.h> /* Definition of FUTEX_* constants */ … … 114 112 static inline bool register_select( single_acquisition_lock & this, select_node & node ) { return register_select( (blocking_lock &)this, node ); } 115 113 static inline bool unregister_select( single_acquisition_lock & this, select_node & node ) { return unregister_select( (blocking_lock &)this, node ); } 116 static inline bool on_selected( single_acquisition_lock & this, select_node & node ) { returnon_selected( (blocking_lock &)this, node ); }114 static inline void on_selected( single_acquisition_lock & this, select_node & node ) { on_selected( (blocking_lock &)this, node ); } 117 115 118 116 //---------- … … 131 129 static inline bool register_select( owner_lock & this, select_node & node ) { return register_select( (blocking_lock &)this, node ); } 132 130 static inline bool unregister_select( owner_lock & this, select_node & node ) { return unregister_select( (blocking_lock &)this, node ); } 133 static inline bool on_selected( owner_lock & this, select_node & node ) { returnon_selected( (blocking_lock &)this, node ); }131 static inline void on_selected( owner_lock & this, select_node & node ) { on_selected( (blocking_lock &)this, node ); } 134 132 135 133 //----------------------------------------------------------------------------- … … 621 619 } 622 620 623 static inline bool on_selected( simple_owner_lock & this, select_node & node ) { return true;}621 static inline void on_selected( simple_owner_lock & this, select_node & node ) {} 624 622 625 623 -
libcfa/src/concurrency/select.cfa
r2b78949 r8a930c03 49 49 return false; 50 50 } 51 bool on_selected( select_timeout_node & this, select_node & node ) { return true;}51 void on_selected( select_timeout_node & this, select_node & node ) {} 52 52 53 53 // Gateway routine to wait on duration -
libcfa/src/concurrency/select.hfa
r2b78949 r8a930c03 91 91 // For unregistering a select stmt on a selectable concurrency primitive 92 92 // If true is returned then the corresponding code block is run (only in non-special OR case and only if node status is not RUN) 93 bool unregister_select( T &, select_node & 93 bool unregister_select( T &, select_node & ); 94 94 95 95 // This routine is run on the selecting thread prior to executing the statement corresponding to the select_node 96 96 // passed as an arg to this routine 97 97 // If on_selected returns false, the statement is not run, if it returns true it is run. 98 boolon_selected( T &, select_node & );98 void on_selected( T &, select_node & ); 99 99 }; 100 100 … … 102 102 // Waituntil Helpers 103 103 //============================================================================================= 104 105 static inline void __make_select_node_unsat( select_node & this ) with( this ) { 106 __atomic_store_n( clause_status, __SELECT_UNSAT, __ATOMIC_SEQ_CST ); 107 } 108 static inline void __make_select_node_sat( select_node & this ) with( this ) { 109 __atomic_store_n( clause_status, __SELECT_SAT, __ATOMIC_SEQ_CST ); 110 } 104 111 105 112 // used for the 2-stage avail needed by the special OR case … … 116 123 } 117 124 118 static inline void __make_select_node_unsat( select_node & this ) with( this ) { 119 __atomic_store_n( clause_status, __SELECT_UNSAT, __ATOMIC_SEQ_CST ); 120 } 121 static inline void __make_select_node_sat( select_node & this ) with( this ) { 122 __atomic_store_n( clause_status, __SELECT_SAT, __ATOMIC_SEQ_CST ); 125 // used for the 2-stage avail by the thread who owns a pending node 126 static inline bool __pending_set_other( select_node & other, select_node & mine, unsigned long int val ) with( other ) { 127 /* paranoid */ verify( park_counter == 0p ); 128 /* paranoid */ verify( clause_status != 0p ); 129 130 unsigned long int cmp_status = __SELECT_UNSAT; 131 while( !__atomic_compare_exchange_n( clause_status, &cmp_status, val, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) ) { 132 if ( cmp_status != __SELECT_PENDING ) 133 return false; 134 135 // toggle current status flag to avoid starvation/deadlock 136 __make_select_node_unsat( mine ); 137 cmp_status = __SELECT_UNSAT; 138 if ( !__atomic_compare_exchange_n( mine.clause_status, &cmp_status, __SELECT_PENDING, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) ) 139 return false; 140 cmp_status = __SELECT_UNSAT; 141 } 142 return true; 123 143 } 124 144 … … 188 208 bool register_select( select_timeout_node & this, select_node & node ); 189 209 bool unregister_select( select_timeout_node & this, select_node & node ); 190 boolon_selected( select_timeout_node & this, select_node & node );210 void on_selected( select_timeout_node & this, select_node & node ); 191 211 192 212 // Gateway routines to waituntil on duration -
libcfa/src/containers/lockfree.hfa
r2b78949 r8a930c03 199 199 200 200 forall( T & ) 201 struct LinkData { 202 T * volatile top; // pointer to stack top 203 uintptr_t count; // count each push 204 }; 205 206 forall( T & ) 201 207 union Link { 202 struct { // 32/64-bit x 2 203 T * volatile top; // pointer to stack top 204 uintptr_t count; // count each push 205 }; 208 LinkData(T) data; 206 209 #if __SIZEOF_INT128__ == 16 207 210 __int128 // gcc, 128-bit integer … … 220 223 void ?{}( StackLF(T) & this ) with(this) { stack.atom = 0; } 221 224 222 T * top( StackLF(T) & this ) with(this) { return stack. top; }225 T * top( StackLF(T) & this ) with(this) { return stack.data.top; } 223 226 224 227 void push( StackLF(T) & this, T & n ) with(this) { 225 228 *( &n )`next = stack; // atomic assignment unnecessary, or use CAA 226 229 for () { // busy wait 227 if ( __atomic_compare_exchange_n( &stack.atom, &( &n )`next->atom, (Link(T))@{ {&n, ( &n )`next->count + 1} }.atom, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) ) break; // attempt to update top node230 if ( __atomic_compare_exchange_n( &stack.atom, &( &n )`next->atom, (Link(T))@{ (LinkData(T))@{ &n, ( &n )`next->data.count + 1} }.atom, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) ) break; // attempt to update top node 228 231 } // for 229 232 } // push … … 232 235 Link(T) t @= stack; // atomic assignment unnecessary, or use CAA 233 236 for () { // busy wait 234 if ( t.top == 0p ) return 0p; // empty stack ? 235 if ( __atomic_compare_exchange_n( &stack.atom, &t.atom, (Link(T))@{ {( t.top )`next->top, t.count} }.atom, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) ) return t.top; // attempt to update top node 237 if ( t.data.top == 0p ) return 0p; // empty stack ? 238 Link(T) * next = ( t.data.top )`next; 239 if ( __atomic_compare_exchange_n( &stack.atom, &t.atom, (Link(T))@{ (LinkData(T))@{ next->data.top, t.data.count } }.atom, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) ) return t.data.top; // attempt to update top node 236 240 } // for 237 241 } // pop … … 239 243 bool unsafe_remove( StackLF(T) & this, T * node ) with(this) { 240 244 Link(T) * link = &stack; 241 for() { 242 T * next = link->top; 243 if( next == node ) { 244 link->top = ( node )`next->top; 245 for () { 246 // TODO: Avoiding some problems with double fields access. 247 LinkData(T) * data = &link->data; 248 T * next = (T *)&(*data).top; 249 if ( next == node ) { 250 data->top = ( node )`next->data.top; 245 251 return true; 246 252 } 247 if ( next == 0p ) return false;253 if ( next == 0p ) return false; 248 254 link = ( next )`next; 249 255 } -
libcfa/src/fstream.cfa
r2b78949 r8a930c03 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Apr 9 14:55:54 202213 // Update Count : 51 512 // Last Modified On : Mon Jun 5 22:00:23 2023 13 // Update Count : 518 14 14 // 15 15 … … 117 117 } // for 118 118 if ( file == 0p ) { 119 throw ( Open_Failure){ os };119 throw (open_failure){ os }; 120 120 // abort | IO_MSG "open output file \"" | name | "\"" | nl | strerror( errno ); 121 121 } // if … … 137 137 } // for 138 138 if ( ret == EOF ) { 139 throw ( Close_Failure){ os };139 throw (close_failure){ os }; 140 140 // abort | IO_MSG "close output" | nl | strerror( errno ); 141 141 } // if … … 145 145 ofstream & write( ofstream & os, const char data[], size_t size ) { 146 146 if ( fail( os ) ) { 147 throw ( Write_Failure){ os };147 throw (write_failure){ os }; 148 148 // abort | IO_MSG "attempt write I/O on failed stream"; 149 149 } // if 150 150 151 151 if ( fwrite( data, 1, size, (FILE *)(os.file$) ) != size ) { 152 throw ( Write_Failure){ os };152 throw (write_failure){ os }; 153 153 // abort | IO_MSG "write" | nl | strerror( errno ); 154 154 } // if … … 240 240 } // for 241 241 if ( file == 0p ) { 242 throw ( Open_Failure){ is };242 throw (open_failure){ is }; 243 243 // abort | IO_MSG "open input file \"" | name | "\"" | nl | strerror( errno ); 244 244 } // if … … 260 260 } // for 261 261 if ( ret == EOF ) { 262 throw ( Close_Failure){ is };262 throw (close_failure){ is }; 263 263 // abort | IO_MSG "close input" | nl | strerror( errno ); 264 264 } // if … … 268 268 ifstream & read( ifstream & is, char data[], size_t size ) { 269 269 if ( fail( is ) ) { 270 throw ( Read_Failure){ is };270 throw (read_failure){ is }; 271 271 // abort | IO_MSG "attempt read I/O on failed stream"; 272 272 } // if 273 273 274 274 if ( fread( data, size, 1, (FILE *)(is.file$) ) == 0 ) { 275 throw ( Read_Failure){ is };275 throw (read_failure){ is }; 276 276 // abort | IO_MSG "read" | nl | strerror( errno ); 277 277 } // if … … 318 318 319 319 320 static vtable( Open_Failure) Open_Failure_vt;320 static vtable(open_failure) open_failure_vt; 321 321 322 322 // exception I/O constructors 323 void ?{}( Open_Failure & ex, ofstream & ostream ) with(ex) {324 virtual_table = & Open_Failure_vt;323 void ?{}( open_failure & ex, ofstream & ostream ) with(ex) { 324 virtual_table = &open_failure_vt; 325 325 ostream = &ostream; 326 326 tag = 1; 327 327 } // ?{} 328 328 329 void ?{}( Open_Failure & ex, ifstream & istream ) with(ex) {330 virtual_table = & Open_Failure_vt;329 void ?{}( open_failure & ex, ifstream & istream ) with(ex) { 330 virtual_table = &open_failure_vt; 331 331 istream = &istream; 332 332 tag = 0; … … 334 334 335 335 336 static vtable( Close_Failure) Close_Failure_vt;336 static vtable(close_failure) close_failure_vt; 337 337 338 338 // exception I/O constructors 339 void ?{}( Close_Failure & ex, ofstream & ostream ) with(ex) {340 virtual_table = & Close_Failure_vt;339 void ?{}( close_failure & ex, ofstream & ostream ) with(ex) { 340 virtual_table = &close_failure_vt; 341 341 ostream = &ostream; 342 342 tag = 1; 343 343 } // ?{} 344 344 345 void ?{}( Close_Failure & ex, ifstream & istream ) with(ex) {346 virtual_table = & Close_Failure_vt;345 void ?{}( close_failure & ex, ifstream & istream ) with(ex) { 346 virtual_table = &close_failure_vt; 347 347 istream = &istream; 348 348 tag = 0; … … 350 350 351 351 352 static vtable( Write_Failure) Write_Failure_vt;352 static vtable(write_failure) write_failure_vt; 353 353 354 354 // exception I/O constructors 355 void ?{}( Write_Failure & ex, ofstream & ostream ) with(ex) {356 virtual_table = & Write_Failure_vt;355 void ?{}( write_failure & ex, ofstream & ostream ) with(ex) { 356 virtual_table = &write_failure_vt; 357 357 ostream = &ostream; 358 358 tag = 1; 359 359 } // ?{} 360 360 361 void ?{}( Write_Failure & ex, ifstream & istream ) with(ex) {362 virtual_table = & Write_Failure_vt;361 void ?{}( write_failure & ex, ifstream & istream ) with(ex) { 362 virtual_table = &write_failure_vt; 363 363 istream = &istream; 364 364 tag = 0; … … 366 366 367 367 368 static vtable( Read_Failure) Read_Failure_vt;368 static vtable(read_failure) read_failure_vt; 369 369 370 370 // exception I/O constructors 371 void ?{}( Read_Failure & ex, ofstream & ostream ) with(ex) {372 virtual_table = & Read_Failure_vt;371 void ?{}( read_failure & ex, ofstream & ostream ) with(ex) { 372 virtual_table = &read_failure_vt; 373 373 ostream = &ostream; 374 374 tag = 1; 375 375 } // ?{} 376 376 377 void ?{}( Read_Failure & ex, ifstream & istream ) with(ex) {378 virtual_table = & Read_Failure_vt;377 void ?{}( read_failure & ex, ifstream & istream ) with(ex) { 378 virtual_table = &read_failure_vt; 379 379 istream = &istream; 380 380 tag = 0; 381 381 } // ?{} 382 382 383 // void throw Open_Failure( ofstream & ostream ) {384 // Open_Failure exc = { ostream };383 // void throwopen_failure( ofstream & ostream ) { 384 // open_failure exc = { ostream }; 385 385 // } 386 386 387 // void throw Open_Failure( ifstream & istream ) {388 // Open_Failure exc = { istream };387 // void throwopen_failure( ifstream & istream ) { 388 // open_failure exc = { istream }; 389 389 // } 390 390 -
libcfa/src/fstream.hfa
r2b78949 r8a930c03 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Oct 10 09:37:32 202113 // Update Count : 24 312 // Last Modified On : Mon Jun 5 22:00:20 2023 13 // Update Count : 246 14 14 // 15 15 … … 137 137 138 138 139 exception Open_Failure {139 exception open_failure { 140 140 union { 141 141 ofstream * ostream; … … 146 146 }; 147 147 148 void ?{}( Open_Failure & this, ofstream & );149 void ?{}( Open_Failure & this, ifstream & );148 void ?{}( open_failure & this, ofstream & ); 149 void ?{}( open_failure & this, ifstream & ); 150 150 151 exception Close_Failure {151 exception close_failure { 152 152 union { 153 153 ofstream * ostream; … … 158 158 }; 159 159 160 void ?{}( Close_Failure & this, ofstream & );161 void ?{}( Close_Failure & this, ifstream & );160 void ?{}( close_failure & this, ofstream & ); 161 void ?{}( close_failure & this, ifstream & ); 162 162 163 exception Write_Failure {163 exception write_failure { 164 164 union { 165 165 ofstream * ostream; … … 170 170 }; 171 171 172 void ?{}( Write_Failure & this, ofstream & );173 void ?{}( Write_Failure & this, ifstream & );172 void ?{}( write_failure & this, ofstream & ); 173 void ?{}( write_failure & this, ifstream & ); 174 174 175 exception Read_Failure {175 exception read_failure { 176 176 union { 177 177 ofstream * ostream; … … 182 182 }; 183 183 184 void ?{}( Read_Failure & this, ofstream & );185 void ?{}( Read_Failure & this, ifstream & );184 void ?{}( read_failure & this, ofstream & ); 185 void ?{}( read_failure & this, ifstream & ); 186 186 187 187 // Local Variables: // -
libcfa/src/math.trait.hfa
r2b78949 r8a930c03 10 10 // Created On : Fri Jul 16 15:40:52 2021 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : T hu Feb 2 11:36:56202313 // Update Count : 2 012 // Last Modified On : Tue Jun 6 07:59:17 2023 13 // Update Count : 24 14 14 // 15 15 … … 17 17 18 18 forall( U ) 19 trait Not {19 trait not { 20 20 void ?{}( U &, zero_t ); 21 21 int !?( U ); 22 }; // Not22 }; // not 23 23 24 forall( T | Not( T ) )25 trait Equality {24 forall( T | not( T ) ) 25 trait equality { 26 26 int ?==?( T, T ); 27 27 int ?!=?( T, T ); 28 }; // Equality28 }; // equality 29 29 30 forall( U | Equality( U ) )31 trait Relational {30 forall( U | equality( U ) ) 31 trait relational { 32 32 int ?<?( U, U ); 33 33 int ?<=?( U, U ); 34 34 int ?>?( U, U ); 35 35 int ?>=?( U, U ); 36 }; // Relational36 }; // relational 37 37 38 38 forall ( T ) 39 trait Signed { 39 trait Signed { // must be capitalized, conflict with keyword signed 40 40 T +?( T ); 41 41 T -?( T ); … … 44 44 45 45 forall( U | Signed( U ) ) 46 trait Additive {46 trait additive { 47 47 U ?+?( U, U ); 48 48 U ?-?( U, U ); 49 49 U ?+=?( U &, U ); 50 50 U ?-=?( U &, U ); 51 }; // Additive51 }; // additive 52 52 53 forall( T | Additive( T ) )54 trait Incdec {53 forall( T | additive( T ) ) 54 trait inc_dec { 55 55 void ?{}( T &, one_t ); 56 56 // T ?++( T & ); … … 58 58 // T ?--( T & ); 59 59 // T --?( T & ); 60 }; // Incdec60 }; // inc_dec 61 61 62 forall( U | Incdec( U ) )63 trait Multiplicative {62 forall( U | inc_dec( U ) ) 63 trait multiplicative { 64 64 U ?*?( U, U ); 65 65 U ?/?( U, U ); 66 66 U ?%?( U, U ); 67 67 U ?/=?( U &, U ); 68 }; // Multiplicative68 }; // multiplicative 69 69 70 forall( T | Relational( T ) | Multiplicative( T ) )71 trait Arithmetic {72 }; // Arithmetic70 forall( T | relational( T ) | multiplicative( T ) ) 71 trait arithmetic { 72 }; // arithmetic 73 73 74 74 // Local Variables: // -
libcfa/src/parseconfig.cfa
r2b78949 r8a930c03 144 144 in | nl; // ignore remainder of line 145 145 } // for 146 } catch( Open_Failure * ex; ex->istream == &in ) {146 } catch( open_failure * ex; ex->istream == &in ) { 147 147 delete( kv_pairs ); 148 148 throw *ex; … … 203 203 204 204 205 forall(T | Relational( T ))205 forall(T | relational( T )) 206 206 [ bool ] is_nonnegative( & T value ) { 207 207 T zero_val = 0; … … 209 209 } 210 210 211 forall(T | Relational( T ))211 forall(T | relational( T )) 212 212 [ bool ] is_positive( & T value ) { 213 213 T zero_val = 0; … … 215 215 } 216 216 217 forall(T | Relational( T ))217 forall(T | relational( T )) 218 218 [ bool ] is_nonpositive( & T value ) { 219 219 T zero_val = 0; … … 221 221 } 222 222 223 forall(T | Relational( T ))223 forall(T | relational( T )) 224 224 [ bool ] is_negative( & T value ) { 225 225 T zero_val = 0; -
libcfa/src/parseconfig.hfa
r2b78949 r8a930c03 107 107 108 108 109 forall(T | Relational( T ))109 forall(T | relational( T )) 110 110 [ bool ] is_nonnegative( & T ); 111 111 112 forall(T | Relational( T ))112 forall(T | relational( T )) 113 113 [ bool ] is_positive( & T ); 114 114 115 forall(T | Relational( T ))115 forall(T | relational( T )) 116 116 [ bool ] is_nonpositive( & T ); 117 117 118 forall(T | Relational( T ))118 forall(T | relational( T )) 119 119 [ bool ] is_negative( & T ); 120 120 -
libcfa/src/rational.cfa
r2b78949 r8a930c03 10 10 // Created On : Wed Apr 6 17:54:28 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Aug 25 18:09:58 202213 // Update Count : 19 412 // Last Modified On : Mon Jun 5 22:49:06 2023 13 // Update Count : 196 14 14 // 15 15 … … 20 20 #pragma GCC visibility push(default) 21 21 22 forall( T | Arithmetic( T ) ) {22 forall( T | arithmetic( T ) ) { 23 23 // helper routines 24 24 … … 39 39 abort | "Invalid rational number construction: denominator cannot be equal to 0."; 40 40 } // exit 41 if ( d < (T){0} ) { d = -d; n = -n; } 41 if ( d < (T){0} ) { d = -d; n = -n; } // move sign to numerator 42 42 return gcd( abs( n ), d ); // simplify 43 } // Rationalnumber::simplify43 } // simplify 44 44 45 45 // constructors 46 46 47 void ?{}( Rational(T) & r, zero_t ) {47 void ?{}( rational(T) & r, zero_t ) { 48 48 r{ (T){0}, (T){1} }; 49 49 } // rational 50 50 51 void ?{}( Rational(T) & r, one_t ) {51 void ?{}( rational(T) & r, one_t ) { 52 52 r{ (T){1}, (T){1} }; 53 53 } // rational 54 54 55 void ?{}( Rational(T) & r ) {55 void ?{}( rational(T) & r ) { 56 56 r{ (T){0}, (T){1} }; 57 57 } // rational 58 58 59 void ?{}( Rational(T) & r, T n ) {59 void ?{}( rational(T) & r, T n ) { 60 60 r{ n, (T){1} }; 61 61 } // rational 62 62 63 void ?{}( Rational(T) & r, T n, T d ) {64 T t = simplify( n, d ); // simplify63 void ?{}( rational(T) & r, T n, T d ) { 64 T t = simplify( n, d ); // simplify 65 65 r.[numerator, denominator] = [n / t, d / t]; 66 66 } // rational … … 68 68 // getter for numerator/denominator 69 69 70 T numerator( Rational(T) r ) {70 T numerator( rational(T) r ) { 71 71 return r.numerator; 72 72 } // numerator 73 73 74 T denominator( Rational(T) r ) {74 T denominator( rational(T) r ) { 75 75 return r.denominator; 76 76 } // denominator 77 77 78 [ T, T ] ?=?( & [ T, T ] dest, Rational(T) src ) {78 [ T, T ] ?=?( & [ T, T ] dest, rational(T) src ) { 79 79 return dest = src.[ numerator, denominator ]; 80 80 } // ?=? … … 82 82 // setter for numerator/denominator 83 83 84 T numerator( Rational(T) r, T n ) {84 T numerator( rational(T) r, T n ) { 85 85 T prev = r.numerator; 86 T t = gcd( abs( n ), r.denominator ); 86 T t = gcd( abs( n ), r.denominator ); // simplify 87 87 r.[numerator, denominator] = [n / t, r.denominator / t]; 88 88 return prev; 89 89 } // numerator 90 90 91 T denominator( Rational(T) r, T d ) {91 T denominator( rational(T) r, T d ) { 92 92 T prev = r.denominator; 93 T t = simplify( r.numerator, d ); // simplify93 T t = simplify( r.numerator, d ); // simplify 94 94 r.[numerator, denominator] = [r.numerator / t, d / t]; 95 95 return prev; … … 98 98 // comparison 99 99 100 int ?==?( Rational(T) l, Rational(T) r ) {100 int ?==?( rational(T) l, rational(T) r ) { 101 101 return l.numerator * r.denominator == l.denominator * r.numerator; 102 102 } // ?==? 103 103 104 int ?!=?( Rational(T) l, Rational(T) r ) {104 int ?!=?( rational(T) l, rational(T) r ) { 105 105 return ! ( l == r ); 106 106 } // ?!=? 107 107 108 int ?!=?( Rational(T) l, zero_t ) {109 return ! ( l == ( Rational(T)){ 0 } );108 int ?!=?( rational(T) l, zero_t ) { 109 return ! ( l == (rational(T)){ 0 } ); 110 110 } // ?!=? 111 111 112 int ?<?( Rational(T) l, Rational(T) r ) {112 int ?<?( rational(T) l, rational(T) r ) { 113 113 return l.numerator * r.denominator < l.denominator * r.numerator; 114 114 } // ?<? 115 115 116 int ?<=?( Rational(T) l, Rational(T) r ) {116 int ?<=?( rational(T) l, rational(T) r ) { 117 117 return l.numerator * r.denominator <= l.denominator * r.numerator; 118 118 } // ?<=? 119 119 120 int ?>?( Rational(T) l, Rational(T) r ) {120 int ?>?( rational(T) l, rational(T) r ) { 121 121 return ! ( l <= r ); 122 122 } // ?>? 123 123 124 int ?>=?( Rational(T) l, Rational(T) r ) {124 int ?>=?( rational(T) l, rational(T) r ) { 125 125 return ! ( l < r ); 126 126 } // ?>=? … … 128 128 // arithmetic 129 129 130 Rational(T) +?( Rational(T) r ) {131 return ( Rational(T)){ r.numerator, r.denominator };130 rational(T) +?( rational(T) r ) { 131 return (rational(T)){ r.numerator, r.denominator }; 132 132 } // +? 133 133 134 Rational(T) -?( Rational(T) r ) {135 return ( Rational(T)){ -r.numerator, r.denominator };134 rational(T) -?( rational(T) r ) { 135 return (rational(T)){ -r.numerator, r.denominator }; 136 136 } // -? 137 137 138 Rational(T) ?+?( Rational(T) l, Rational(T) r ) {138 rational(T) ?+?( rational(T) l, rational(T) r ) { 139 139 if ( l.denominator == r.denominator ) { // special case 140 return ( Rational(T)){ l.numerator + r.numerator, l.denominator };140 return (rational(T)){ l.numerator + r.numerator, l.denominator }; 141 141 } else { 142 return ( Rational(T)){ l.numerator * r.denominator + l.denominator * r.numerator, l.denominator * r.denominator };142 return (rational(T)){ l.numerator * r.denominator + l.denominator * r.numerator, l.denominator * r.denominator }; 143 143 } // if 144 144 } // ?+? 145 145 146 Rational(T) ?+=?( Rational(T) & l, Rational(T) r ) {146 rational(T) ?+=?( rational(T) & l, rational(T) r ) { 147 147 l = l + r; 148 148 return l; 149 149 } // ?+? 150 150 151 Rational(T) ?+=?( Rational(T) & l, one_t ) {152 l = l + ( Rational(T)){ 1 };151 rational(T) ?+=?( rational(T) & l, one_t ) { 152 l = l + (rational(T)){ 1 }; 153 153 return l; 154 154 } // ?+? 155 155 156 Rational(T) ?-?( Rational(T) l, Rational(T) r ) {156 rational(T) ?-?( rational(T) l, rational(T) r ) { 157 157 if ( l.denominator == r.denominator ) { // special case 158 return ( Rational(T)){ l.numerator - r.numerator, l.denominator };158 return (rational(T)){ l.numerator - r.numerator, l.denominator }; 159 159 } else { 160 return ( Rational(T)){ l.numerator * r.denominator - l.denominator * r.numerator, l.denominator * r.denominator };160 return (rational(T)){ l.numerator * r.denominator - l.denominator * r.numerator, l.denominator * r.denominator }; 161 161 } // if 162 162 } // ?-? 163 163 164 Rational(T) ?-=?( Rational(T) & l, Rational(T) r ) {164 rational(T) ?-=?( rational(T) & l, rational(T) r ) { 165 165 l = l - r; 166 166 return l; 167 167 } // ?-? 168 168 169 Rational(T) ?-=?( Rational(T) & l, one_t ) {170 l = l - ( Rational(T)){ 1 };169 rational(T) ?-=?( rational(T) & l, one_t ) { 170 l = l - (rational(T)){ 1 }; 171 171 return l; 172 172 } // ?-? 173 173 174 Rational(T) ?*?( Rational(T) l, Rational(T) r ) {175 return ( Rational(T)){ l.numerator * r.numerator, l.denominator * r.denominator };174 rational(T) ?*?( rational(T) l, rational(T) r ) { 175 return (rational(T)){ l.numerator * r.numerator, l.denominator * r.denominator }; 176 176 } // ?*? 177 177 178 Rational(T) ?*=?( Rational(T) & l, Rational(T) r ) {178 rational(T) ?*=?( rational(T) & l, rational(T) r ) { 179 179 return l = l * r; 180 180 } // ?*? 181 181 182 Rational(T) ?/?( Rational(T) l, Rational(T) r ) {182 rational(T) ?/?( rational(T) l, rational(T) r ) { 183 183 if ( r.numerator < (T){0} ) { 184 184 r.[numerator, denominator] = [-r.numerator, -r.denominator]; 185 185 } // if 186 return ( Rational(T)){ l.numerator * r.denominator, l.denominator * r.numerator };186 return (rational(T)){ l.numerator * r.denominator, l.denominator * r.numerator }; 187 187 } // ?/? 188 188 189 Rational(T) ?/=?( Rational(T) & l, Rational(T) r ) {189 rational(T) ?/=?( rational(T) & l, rational(T) r ) { 190 190 return l = l / r; 191 191 } // ?/? … … 194 194 195 195 forall( istype & | istream( istype ) | { istype & ?|?( istype &, T & ); } ) 196 istype & ?|?( istype & is, Rational(T) & r ) {196 istype & ?|?( istype & is, rational(T) & r ) { 197 197 is | r.numerator | r.denominator; 198 198 T t = simplify( r.numerator, r.denominator ); … … 203 203 204 204 forall( ostype & | ostream( ostype ) | { ostype & ?|?( ostype &, T ); } ) { 205 ostype & ?|?( ostype & os, Rational(T) r ) {205 ostype & ?|?( ostype & os, rational(T) r ) { 206 206 return os | r.numerator | '/' | r.denominator; 207 207 } // ?|? 208 208 209 void ?|?( ostype & os, Rational(T) r ) {209 void ?|?( ostype & os, rational(T) r ) { 210 210 (ostype &)(os | r); ends( os ); 211 211 } // ?|? … … 213 213 } // distribution 214 214 215 forall( T | Arithmetic( T ) | { T ?\?( T, unsigned long ); } ) {216 Rational(T) ?\?( Rational(T) x, long int y ) {215 forall( T | arithmetic( T ) | { T ?\?( T, unsigned long ); } ) { 216 rational(T) ?\?( rational(T) x, long int y ) { 217 217 if ( y < 0 ) { 218 return ( Rational(T)){ x.denominator \ -y, x.numerator \ -y };218 return (rational(T)){ x.denominator \ -y, x.numerator \ -y }; 219 219 } else { 220 return ( Rational(T)){ x.numerator \ y, x.denominator \ y };220 return (rational(T)){ x.numerator \ y, x.denominator \ y }; 221 221 } // if 222 222 } // ?\? 223 223 224 Rational(T) ?\=?( Rational(T) & x, long int y ) {224 rational(T) ?\=?( rational(T) & x, long int y ) { 225 225 return x = x \ y; 226 226 } // ?\? … … 229 229 // conversion 230 230 231 forall( T | Arithmetic( T ) | { double convert( T ); } )232 double widen( Rational(T) r ) {231 forall( T | arithmetic( T ) | { double convert( T ); } ) 232 double widen( rational(T) r ) { 233 233 return convert( r.numerator ) / convert( r.denominator ); 234 234 } // widen 235 235 236 forall( T | Arithmetic( T ) | { double convert( T ); T convert( double ); } )237 Rational(T) narrow( double f, T md ) {236 forall( T | arithmetic( T ) | { double convert( T ); T convert( double ); } ) 237 rational(T) narrow( double f, T md ) { 238 238 // http://www.ics.uci.edu/~eppstein/numth/frap.c 239 if ( md <= (T){1} ) { // maximum fractional digits too small?240 return ( Rational(T)){ convert( f ), (T){1}};// truncate fraction239 if ( md <= (T){1} ) { // maximum fractional digits too small? 240 return (rational(T)){ convert( f ), (T){1}}; // truncate fraction 241 241 } // if 242 242 … … 260 260 if ( f > (double)0x7FFFFFFF ) break; // representation failure 261 261 } // for 262 return ( Rational(T)){ m00, m10 };262 return (rational(T)){ m00, m10 }; 263 263 } // narrow 264 264 -
libcfa/src/rational.hfa
r2b78949 r8a930c03 12 12 // Created On : Wed Apr 6 17:56:25 2016 13 13 // Last Modified By : Peter A. Buhr 14 // Last Modified On : Tue Jul 20 17:45:29 202115 // Update Count : 11 814 // Last Modified On : Mon Jun 5 22:49:05 2023 15 // Update Count : 119 16 16 // 17 17 … … 19 19 20 20 #include "iostream.hfa" 21 #include "math.trait.hfa" // Arithmetic21 #include "math.trait.hfa" // arithmetic 22 22 23 23 // implementation 24 24 25 forall( T | Arithmetic( T ) ) {26 struct Rational {25 forall( T | arithmetic( T ) ) { 26 struct rational { 27 27 T numerator, denominator; // invariant: denominator > 0 28 }; // Rational28 }; // rational 29 29 30 30 // constructors 31 31 32 void ?{}( Rational(T) & r );33 void ?{}( Rational(T) & r, zero_t );34 void ?{}( Rational(T) & r, one_t );35 void ?{}( Rational(T) & r, T n );36 void ?{}( Rational(T) & r, T n, T d );32 void ?{}( rational(T) & r ); 33 void ?{}( rational(T) & r, zero_t ); 34 void ?{}( rational(T) & r, one_t ); 35 void ?{}( rational(T) & r, T n ); 36 void ?{}( rational(T) & r, T n, T d ); 37 37 38 38 // numerator/denominator getter 39 39 40 T numerator( Rational(T) r );41 T denominator( Rational(T) r );42 [ T, T ] ?=?( & [ T, T ] dest, Rational(T) src );40 T numerator( rational(T) r ); 41 T denominator( rational(T) r ); 42 [ T, T ] ?=?( & [ T, T ] dest, rational(T) src ); 43 43 44 44 // numerator/denominator setter 45 45 46 T numerator( Rational(T) r, T n );47 T denominator( Rational(T) r, T d );46 T numerator( rational(T) r, T n ); 47 T denominator( rational(T) r, T d ); 48 48 49 49 // comparison 50 50 51 int ?==?( Rational(T) l, Rational(T) r );52 int ?!=?( Rational(T) l, Rational(T) r );53 int ?!=?( Rational(T) l, zero_t ); // => !54 int ?<?( Rational(T) l, Rational(T) r );55 int ?<=?( Rational(T) l, Rational(T) r );56 int ?>?( Rational(T) l, Rational(T) r );57 int ?>=?( Rational(T) l, Rational(T) r );51 int ?==?( rational(T) l, rational(T) r ); 52 int ?!=?( rational(T) l, rational(T) r ); 53 int ?!=?( rational(T) l, zero_t ); // => ! 54 int ?<?( rational(T) l, rational(T) r ); 55 int ?<=?( rational(T) l, rational(T) r ); 56 int ?>?( rational(T) l, rational(T) r ); 57 int ?>=?( rational(T) l, rational(T) r ); 58 58 59 59 // arithmetic 60 60 61 Rational(T) +?( Rational(T) r );62 Rational(T) -?( Rational(T) r );63 Rational(T) ?+?( Rational(T) l, Rational(T) r );64 Rational(T) ?+=?( Rational(T) & l, Rational(T) r );65 Rational(T) ?+=?( Rational(T) & l, one_t ); // => ++?, ?++66 Rational(T) ?-?( Rational(T) l, Rational(T) r );67 Rational(T) ?-=?( Rational(T) & l, Rational(T) r );68 Rational(T) ?-=?( Rational(T) & l, one_t ); // => --?, ?--69 Rational(T) ?*?( Rational(T) l, Rational(T) r );70 Rational(T) ?*=?( Rational(T) & l, Rational(T) r );71 Rational(T) ?/?( Rational(T) l, Rational(T) r );72 Rational(T) ?/=?( Rational(T) & l, Rational(T) r );61 rational(T) +?( rational(T) r ); 62 rational(T) -?( rational(T) r ); 63 rational(T) ?+?( rational(T) l, rational(T) r ); 64 rational(T) ?+=?( rational(T) & l, rational(T) r ); 65 rational(T) ?+=?( rational(T) & l, one_t ); // => ++?, ?++ 66 rational(T) ?-?( rational(T) l, rational(T) r ); 67 rational(T) ?-=?( rational(T) & l, rational(T) r ); 68 rational(T) ?-=?( rational(T) & l, one_t ); // => --?, ?-- 69 rational(T) ?*?( rational(T) l, rational(T) r ); 70 rational(T) ?*=?( rational(T) & l, rational(T) r ); 71 rational(T) ?/?( rational(T) l, rational(T) r ); 72 rational(T) ?/=?( rational(T) & l, rational(T) r ); 73 73 74 74 // I/O 75 75 forall( istype & | istream( istype ) | { istype & ?|?( istype &, T & ); } ) 76 istype & ?|?( istype &, Rational(T) & );76 istype & ?|?( istype &, rational(T) & ); 77 77 78 78 forall( ostype & | ostream( ostype ) | { ostype & ?|?( ostype &, T ); } ) { 79 ostype & ?|?( ostype &, Rational(T) );80 void ?|?( ostype &, Rational(T) );79 ostype & ?|?( ostype &, rational(T) ); 80 void ?|?( ostype &, rational(T) ); 81 81 } // distribution 82 82 } // distribution 83 83 84 forall( T | Arithmetic( T ) | { T ?\?( T, unsigned long ); } ) {85 Rational(T) ?\?( Rational(T) x, long int y );86 Rational(T) ?\=?( Rational(T) & x, long int y );84 forall( T | arithmetic( T ) | { T ?\?( T, unsigned long ); } ) { 85 rational(T) ?\?( rational(T) x, long int y ); 86 rational(T) ?\=?( rational(T) & x, long int y ); 87 87 } // distribution 88 88 89 89 // conversion 90 forall( T | Arithmetic( T ) | { double convert( T ); } )91 double widen( Rational(T) r );92 forall( T | Arithmetic( T ) | { double convert( T ); T convert( double );} )93 Rational(T) narrow( double f, T md );90 forall( T | arithmetic( T ) | { double convert( T ); } ) 91 double widen( rational(T) r ); 92 forall( T | arithmetic( T ) | { double convert( T ); T convert( double );} ) 93 rational(T) narrow( double f, T md ); 94 94 95 95 // Local Variables: //
Note: See TracChangeset
for help on using the changeset viewer.