Changeset 81ab5eb
- Timestamp:
- Mar 29, 2026, 9:52:51 PM (2 days ago)
- Branches:
- master
- Children:
- e6e250d
- Parents:
- 00675ed4
- Files:
-
- 10 edited
-
libcfa/src/bits/sequence.hfa (modified) (1 diff)
-
libcfa/src/collections/list.hfa (modified) (3 diffs)
-
libcfa/src/collections/list2.hfa (modified) (13 diffs)
-
libcfa/src/concurrency/channel.hfa (modified) (15 diffs)
-
libcfa/src/concurrency/cofor.hfa (modified) (1 diff)
-
libcfa/src/concurrency/future.hfa (modified) (3 diffs)
-
libcfa/src/concurrency/io.cfa (modified) (4 diffs)
-
libcfa/src/concurrency/kernel.cfa (modified) (2 diffs)
-
libcfa/src/concurrency/select.hfa (modified) (2 diffs)
-
tests/list/dlist-insert-remove.cfa (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/bits/sequence.hfa
r00675ed4 r81ab5eb 65 65 void ?{}( Sequence(T) & s ) with( s ) { 66 66 ((Collection &)s){}; 67 } // post: isEmpty()67 } // post: empty() 68 68 } 69 69 -
libcfa/src/collections/list.hfa
r00675ed4 r81ab5eb 10 10 // Created On : Wed Apr 22 18:00:00 2020 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Mar 27 08:02:56202613 // Update Count : 9912 // Last Modified On : Sun Mar 29 21:20:44 2026 13 // Update Count : 101 14 14 // 15 15 … … 206 206 } 207 207 208 bool isEmpty( dlist( tE, tLinks ) & list ) { 208 bool isEmpty( dlist( tE, tLinks ) & list ) { // deprecated 209 209 return empty( list ); 210 210 } … … 413 413 // Transfer the "from" list to the end of this sequence; the "from" list is empty after the transfer. 414 414 // void transfer( dlist( tE, tLinks ) & to, dlist( tE, tLinks ) & from ) { 415 // if ( isEmpty( from ) ) return; // "from" list empty ?416 // if ( isEmpty( to ) ) { // "to" list empty ?415 // if ( empty( from ) ) return; // "from" list empty ? 416 // if ( empty( to ) ) { // "to" list empty ? 417 417 // root = from.root; 418 418 // } else { // "to" list not empty -
libcfa/src/collections/list2.hfa
r00675ed4 r81ab5eb 19 19 // Created On : Wed Apr 22 18:00:00 2020 20 20 // Last Modified By : Peter A. Buhr 21 // Last Modified On : Tue Mar 24 22:20:56202622 // Update Count : 821 // Last Modified On : Sun Mar 29 21:47:53 2026 22 // Update Count : 12 23 23 // 24 24 … … 206 206 }; 207 207 208 static inline tE * $get_list_origin_addr( dlist(tE, tLinks) & l st ) {208 static inline tE * $get_list_origin_addr( dlist(tE, tLinks) & list ) { 209 209 dlink(tE) & link_from_null = ( * (tE *) 0p )`inner; 210 210 ptrdiff_t link_offset = (ptrdiff_t) & link_from_null; 211 size_t origin_addr = ((size_t) & l st) - link_offset;211 size_t origin_addr = ((size_t) & list) - link_offset; 212 212 size_t preResult = ORIGIN_TAG_ENABL( origin_addr ); 213 213 return (tE *)preResult; … … 430 430 } 431 431 432 static inline tE & first( dlist(tE, tLinks) & l st ) {433 verify (&l st != 0p);434 dlink(tE) * firstLnk = l st.next;432 static inline tE & first( dlist(tE, tLinks) & list ) { 433 verify (&list != 0p); 434 dlink(tE) * firstLnk = list.next; 435 435 if (ORIGIN_TAG_QUERY((size_t)firstLnk)) return * 0p; 436 436 tytagref( tLinks, dlink(tE) ) firstLnkTagged = {*firstLnk}; 437 437 return downcast$( firstLnkTagged ); 438 438 } 439 static inline tE & last ( dlist(tE, tLinks) & l st ) {440 verify (&l st != 0p);441 dlink(tE) * lastLnk = l st.prev;439 static inline tE & last ( dlist(tE, tLinks) & list ) { 440 verify (&list != 0p); 441 dlink(tE) * lastLnk = list.prev; 442 442 if (ORIGIN_TAG_QUERY((size_t)lastLnk)) return * 0p; 443 443 tytagref( tLinks, dlink(tE) ) lastLnkTagged = {*lastLnk}; … … 445 445 } 446 446 447 static inline bool isEmpty( dlist(tE, tLinks) & lst ) {448 verify (&l st != 0p);449 if ( & first(l st) == 0p || & last(lst) == 0p ) {450 verify( & last(l st) == 0p && & last(lst) == 0p );447 static inline bool empty( dlist(tE, tLinks) & list ) { 448 verify (&list != 0p); 449 if ( & first(list) == 0p || & last(list) == 0p ) { 450 verify( & last(list) == 0p && & last(list) == 0p ); 451 451 return true; 452 452 } 453 453 return false; 454 } 455 456 static inline bool isEmpty( dlist(tE, tLinks) & list ) __attribute__ ((deprecated)); 457 static inline bool isEmpty( dlist(tE, tLinks) & list ) { 458 return empty( list ); 454 459 } 455 460 … … 469 474 } 470 475 471 static inline tE & iter( dlist(tE, tLinks) & l st ) {472 tE * origin = $get_list_origin_addr( l st );476 static inline tE & iter( dlist(tE, tLinks) & list ) { 477 tE * origin = $get_list_origin_addr( list ); 473 478 return *origin; 474 479 } … … 538 543 // Applies knowledge of tag pattern around head (unknown to optimizer) to reduce runtime tag operations. 539 544 540 static inline void insert_first( dlist(tE, tLinks) &l st, tE & e ) {545 static inline void insert_first( dlist(tE, tLinks) &list, tE & e ) { 541 546 dlink(tE) & linkToInsert = e`inner; 542 547 NOLOOSE( … … 548 553 verify(ORIGIN_TAG_CLEAR((size_t)linkToInsert.next) == (size_t)&linkToInsert); 549 554 ) 550 dlink(tE) & list_pos_links = l st;555 dlink(tE) & list_pos_links = list; 551 556 MAYBE_INSERT_READ_EARLY( 552 557 dlink(tE) & afterLinks = * (dlink(tE) *) ORIGIN_TAG_CLEAR( (size_t) list_pos_links.next ); … … 577 582 } 578 583 579 static inline void insert_last( dlist(tE, tLinks) &l st, tE & e ) {584 static inline void insert_last( dlist(tE, tLinks) &list, tE & e ) { 580 585 dlink(tE) & linkToInsert = e`inner; 581 586 NOLOOSE( … … 587 592 verify(ORIGIN_TAG_CLEAR((size_t)linkToInsert.prev) == (size_t)&linkToInsert); 588 593 ) 589 dlink(tE) & list_pos_links = l st;594 dlink(tE) & list_pos_links = list; 590 595 MAYBE_INSERT_READ_EARLY( 591 596 dlink(tE) & beforeLinks = * (dlink(tE) *) ORIGIN_TAG_CLEAR( (size_t) list_pos_links.prev ); … … 630 635 } 631 636 632 static inline tE & remove_first( dlist(tE, tLinks) &l st ) {633 verify (&l st != 0p);634 dlink(tE) & list_links = l st;637 static inline tE & remove_first( dlist(tE, tLinks) &list ) { 638 verify (&list != 0p); 639 dlink(tE) & list_links = list; 635 640 // call is valid on empty list; when so, list_links.next and after_links.prev have otags set 636 641 … … 657 662 } 658 663 659 static inline tE & remove_last( dlist(tE, tLinks) &l st ) {660 verify (&l st != 0p);661 dlink(tE) & list_links = l st;664 static inline tE & remove_last( dlist(tE, tLinks) &list ) { 665 verify (&list != 0p); 666 dlink(tE) & list_links = list; 662 667 // call is valid on empty list; when so, list_links.prev and before_links.next have otags set 663 668 … … 684 689 } 685 690 686 static inline tE & try_pop_first( dlist(tE, tLinks) &l st ) {687 tE & first_inlist = first(l st);691 static inline tE & try_pop_first( dlist(tE, tLinks) &list ) { 692 tE & first_inlist = first(list); 688 693 tE & first_item = first_inlist; 689 694 if (&first_item) remove(first_inlist); // TODO: should it use pop_front? … … 691 696 } 692 697 693 static inline tE & try_pop_last( dlist(tE, tLinks) &l st ) {694 tE & last_inlist = last(l st);698 static inline tE & try_pop_last( dlist(tE, tLinks) &list ) { 699 tE & last_inlist = last(list); 695 700 tE & last_item = last_inlist; 696 701 if (&last_item) remove(last_inlist); // TODO: should it use pop_back? -
libcfa/src/concurrency/channel.hfa
r00675ed4 r81ab5eb 117 117 printf("Channel %p Producer Blocks: %lu,\tProducer Ops: %lu,\t%.2f%% of Producer ops blocked\n", &c, c_blocks, c_ops, ((double)c_blocks)/c_ops * 100); 118 118 #endif 119 verifyf( __handle_waituntil_OR( cons ) || __handle_waituntil_OR( prods ) || isEmpty( cons ) && isEmpty( prods ),119 verifyf( __handle_waituntil_OR( cons ) || __handle_waituntil_OR( prods ) || empty( cons ) && empty( prods ), 120 120 "Attempted to delete channel with waiting threads (Deadlock).\n" ); 121 121 if ( size != 0 ) delete( buffer ); … … 123 123 size_t get_count( channel(T) & chan ) with(chan) { return __atomic_load_n( &count, __ATOMIC_RELAXED ); } 124 124 size_t get_size( channel(T) & chan ) with(chan) { return __atomic_load_n( &size, __ATOMIC_RELAXED ); } 125 bool has_waiters( channel(T) & chan ) with(chan) { return ! isEmpty( cons ) || ! isEmpty( prods ); }126 bool has_waiting_consumers( channel(T) & chan ) with(chan) { return ! isEmpty( cons ); }127 bool has_waiting_producers( channel(T) & chan ) with(chan) { return ! isEmpty( prods ); }125 bool has_waiters( channel(T) & chan ) with(chan) { return ! empty( cons ) || ! empty( prods ); } 126 bool has_waiting_consumers( channel(T) & chan ) with(chan) { return ! empty( cons ); } 127 bool has_waiting_producers( channel(T) & chan ) with(chan) { return ! empty( prods ); } 128 128 129 129 // closes the channel and notifies all blocked threads … … 164 164 void flush( channel(T) & chan, T elem ) with(chan) { 165 165 lock( mutex_lock ); 166 while ( count == 0 && ! isEmpty( cons ) ) {166 while ( count == 0 && ! empty( cons ) ) { 167 167 __cons_handoff( chan, elem ); 168 168 } … … 186 186 187 187 ConsEmpty: 188 if ( ! isEmpty( cons ) ) {188 if ( ! empty( cons ) ) { 189 189 if ( ! __handle_waituntil_OR( cons ) ) break ConsEmpty; 190 190 __cons_handoff( chan, elem ); … … 233 233 // buffer count must be zero if cons are blocked (also handles zero-size case) 234 234 ConsEmpty: 235 if ( ! isEmpty( cons ) ) {235 if ( ! empty( cons ) ) { 236 236 if ( ! __handle_waituntil_OR( cons ) ) break ConsEmpty; 237 237 __cons_handoff( chan, elem ); … … 261 261 count -= 1; 262 262 front = (front + 1) % size; 263 if (count == size - 1 && ! isEmpty( prods ) ) {263 if (count == size - 1 && ! empty( prods ) ) { 264 264 if ( ! __handle_waituntil_OR( prods ) ) return; 265 265 __buf_insert( chan, *(T *)first( prods ).extra ); // do waiting producer work … … 276 276 277 277 ZeroSize: 278 if ( size == 0 && ! isEmpty( prods ) ) {278 if ( size == 0 && ! empty( prods ) ) { 279 279 if ( ! __handle_waituntil_OR( prods ) ) break ZeroSize; 280 280 __prods_handoff( chan, retval ); … … 332 332 // have to check for the zero size channel case 333 333 ZeroSize: 334 if ( size == 0 && ! isEmpty( prods ) ) {334 if ( size == 0 && ! empty( prods ) ) { 335 335 if ( ! __handle_waituntil_OR( prods ) ) break ZeroSize; 336 336 __prods_handoff( chan, retval ); … … 384 384 // special case of __handle_waituntil_OR, that does some work to avoid starvation/deadlock case 385 385 bool __handle_pending( dlist( select_node ) & queue, select_node & mine ) { 386 while ( ! isEmpty( queue ) ) {386 while ( ! empty( queue ) ) { 387 387 // if node not a special OR case or if we win the special OR case race break 388 388 if ( ! first( queue ).clause_status || first( queue ).park_counter || __pending_set_other( first( queue ), mine, ((unsigned long int)(&(first( queue )))) ) ) … … 421 421 if ( ! node.park_counter ) { 422 422 // are we special case OR and front of cons is also special case OR 423 if ( ! unlikely(closed) && ! isEmpty( prods ) && first( prods ).clause_status && ! first( prods ).park_counter ) {423 if ( ! unlikely(closed) && ! empty( prods ) && first( prods ).clause_status && ! first( prods ).park_counter ) { 424 424 if ( ! __make_select_node_pending( node ) ) { 425 425 unlock( mutex_lock ); … … 437 437 } 438 438 // check if we can complete operation. If so race to establish winner in special OR case 439 if ( count != 0 || ! isEmpty( prods ) || unlikely(closed) ) {439 if ( count != 0 || ! empty( prods ) || unlikely(closed) ) { 440 440 if ( ! __make_select_node_available( node ) ) { // we didn't win the race so give up on registering 441 441 unlock( mutex_lock ); … … 453 453 // have to check for the zero size channel case 454 454 ZeroSize: 455 if ( size == 0 && ! isEmpty( prods ) ) {455 if ( size == 0 && ! empty( prods ) ) { 456 456 if ( ! __handle_waituntil_OR( prods ) ) break ZeroSize; 457 457 __prods_handoff( *chan, *ret ); … … 522 522 if ( ! node.park_counter ) { 523 523 // are we special case OR and front of cons is also special case OR 524 if ( ! unlikely(closed) && ! isEmpty( cons ) && first( cons ).clause_status && ! first( cons ).park_counter ) {524 if ( ! unlikely(closed) && ! empty( cons ) && first( cons ).clause_status && ! first( cons ).park_counter ) { 525 525 if ( ! __make_select_node_pending( node ) ) { 526 526 unlock( mutex_lock ); … … 537 537 } 538 538 // check if we can complete operation. If so race to establish winner in special OR case 539 if ( count != size || ! isEmpty( cons ) || unlikely(closed) ) {539 if ( count != size || ! empty( cons ) || unlikely(closed) ) { 540 540 if ( ! __make_select_node_available( node ) ) { // we didn't win the race so give up on registering 541 541 unlock( mutex_lock ); … … 554 554 // handle blocked consumer case via handoff (buffer is implicitly empty) 555 555 ConsEmpty: 556 if ( ! isEmpty( cons ) ) {556 if ( ! empty( cons ) ) { 557 557 if ( ! __handle_waituntil_OR( cons ) ) break ConsEmpty; 558 558 __cons_handoff( *chan, elem ); -
libcfa/src/concurrency/cofor.hfa
r00675ed4 r81ab5eb 33 33 34 34 void main( cofor_runner & this ) with(this) { 35 while ( ! done || ! isEmpty( items ) ) {35 while ( ! done || ! empty( items ) ) { 36 36 lock( mutex_lock ); 37 37 runner_node * node = &remove_first( items ); -
libcfa/src/concurrency/future.hfa
r00675ed4 r81ab5eb 10 10 // Created On : Wed Jan 06 17:33:18 2021 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Nov 24 16:08:52 202513 // Update Count : 22 212 // Last Modified On : Sun Mar 29 21:13:04 2026 13 // Update Count : 223 14 14 // 15 15 … … 173 173 174 174 bool fulfil$( future(T) & fut ) with( fut ) { // helper 175 bool ret_val = ! isEmpty( waiters );175 bool ret_val = ! empty( waiters ); 176 176 state = FUTURE_FULFILLED$; 177 while ( ! isEmpty( waiters ) ) {177 while ( ! empty( waiters ) ) { 178 178 if ( !__handle_waituntil_OR( waiters ) ) // handle special waituntil OR case 179 179 break; // if handle_OR returns false then waiters is empty so break … … 211 211 void reset( future(T) & fut ) with( fut ) { // mark future as empty (for reuse) 212 212 lock( lock ); 213 if ( ! isEmpty( waiters ) ) abort( "Attempting to reset a future with blocked waiters" );213 if ( ! empty( waiters ) ) abort( "Attempting to reset a future with blocked waiters" ); 214 214 state = FUTURE_EMPTY$; 215 215 free( except ); -
libcfa/src/concurrency/io.cfa
r00675ed4 r81ab5eb 594 594 lock( queue.lock __cfaabi_dbg_ctx2 ); 595 595 { 596 was_empty = isEmpty( queue.queue );596 was_empty = empty( queue.queue ); 597 597 598 598 // Add our request to the list … … 632 632 // notify the arbiter that new allocations are available 633 633 static void __ioarbiter_notify( io_arbiter$ & this, io_context$ * ctx ) { 634 /* paranoid */ verify( ! isEmpty( this.pending.queue ) );634 /* paranoid */ verify( ! empty( this.pending.queue ) ); 635 635 /* paranoid */ verify( __preemption_enabled() ); 636 636 … … 642 642 // as long as there are pending allocations try to satisfy them 643 643 // for simplicity do it in FIFO order 644 while( ! isEmpty( this.pending.queue ) ) {644 while( ! empty( this.pending.queue ) ) { 645 645 // get first pending allocs 646 646 __u32 have = ctx->sq.free_ring.tail - ctx->sq.free_ring.head; … … 727 727 // pop each operation one at a time. 728 728 // There is no wait morphing because of the io sq ring 729 while( ! isEmpty( ctx.ext_sq.queue ) ) {729 while( ! empty( ctx.ext_sq.queue ) ) { 730 730 // drop the element from the queue 731 731 __external_io & ei = (__external_io&)remove_first( ctx.ext_sq.queue ); -
libcfa/src/concurrency/kernel.cfa
r00675ed4 r81ab5eb 10 10 // Created On : Tue Jan 17 12:27:26 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Apr 25 07:02:42 202513 // Update Count : 8 212 // Last Modified On : Sun Mar 29 21:20:54 2026 13 // Update Count : 83 14 14 // 15 15 … … 785 785 // update the pointer to the head wait context 786 786 struct __fd_waitctx * wctx = 0; 787 if ( ! isEmpty( this.idles )) wctx = &first( this. idles ).idle_wctx;787 if ( ! empty( this.idles )) wctx = &first( this. idles ).idle_wctx; 788 788 __atomic_store_n(&this.fdw, wctx, __ATOMIC_SEQ_CST); 789 789 } -
libcfa/src/concurrency/select.hfa
r00675ed4 r81ab5eb 11 11 // Created On : Thu Jan 21 19:46:50 2023 12 12 // Last Modified By : Peter A. Buhr 13 // Last Modified On : Sun Nov 23 22:38:36 202514 // Update Count : 813 // Last Modified On : Sun Mar 29 21:12:52 2026 14 // Update Count : 9 15 15 // 16 16 … … 169 169 // Returns true if execution can continue normally and false if the queue has now been drained 170 170 static inline bool __handle_waituntil_OR( dlist( select_node ) & queue ) { 171 if ( isEmpty( queue ) ) return false;171 if ( empty( queue ) ) return false; 172 172 if ( first( queue ).clause_status && ! first( queue ).park_counter ) { 173 while ( ! isEmpty( queue ) ) {173 while ( ! empty( queue ) ) { 174 174 // if node not a special OR case or if we win the special OR case race break 175 175 if ( ! first( queue ).clause_status || first( queue ).park_counter || __make_select_node_available( first( queue ) ) ) -
tests/list/dlist-insert-remove.cfa
r00675ed4 r81ab5eb 1436 1436 // Section 4g 1437 1437 // 1438 // Test cases of isEmpty, isFirst, isLast,1438 // Test cases of empty, isFirst, isLast, 1439 1439 // remove_first, remove_last, modifications via iter 1440 1440 // … … 1449 1449 mary m3 = {3.7}; 1450 1450 1451 dlist(mary) ml; assert( isEmpty( ml ));1452 1453 insert_last(ml, m1); assert(! isEmpty( ml ));1454 insert_last(ml, m2); assert(! isEmpty( ml ));1455 insert_last(ml, m3); assert(! isEmpty( ml ));1451 dlist(mary) ml; assert(empty( ml )); 1452 1453 insert_last(ml, m1); assert(!empty( ml )); 1454 insert_last(ml, m2); assert(!empty( ml )); 1455 insert_last(ml, m3); assert(!empty( ml )); 1456 1456 1457 1457 mary & m1prev = prev( m1 ); … … 1494 1494 // queue, back to front 1495 1495 1496 assert( isEmpty( ml ));1496 assert(empty( ml )); 1497 1497 1498 1498 insert_last(ml, m1); … … 1500 1500 insert_last(ml, m3); 1501 1501 1502 &m1r = & remove_first(ml); assert(! isEmpty( ml ));1503 &m2r = & remove_first(ml); assert(! isEmpty( ml ));1504 &m3r = & remove_first(ml); assert( isEmpty( ml ));1505 &mxr = & remove_first(ml); assert( isEmpty( ml ));1502 &m1r = & remove_first(ml); assert(!empty( ml )); 1503 &m2r = & remove_first(ml); assert(!empty( ml )); 1504 &m3r = & remove_first(ml); assert(empty( ml )); 1505 &mxr = & remove_first(ml); assert(empty( ml )); 1506 1506 1507 1507 assert( &m1r == &m1 ); … … 1516 1516 // queue, front to back 1517 1517 1518 assert( isEmpty( ml ));1518 assert(empty( ml )); 1519 1519 1520 1520 insert_first(ml, m1); … … 1522 1522 insert_first(ml, m3); 1523 1523 1524 &m1r = & remove_last(ml); assert(! isEmpty( ml ));1525 &m2r = & remove_last(ml); assert(! isEmpty( ml ));1526 &m3r = & remove_last(ml); assert( isEmpty( ml ));1527 &mxr = & remove_last(ml); assert( isEmpty( ml ));1524 &m1r = & remove_last(ml); assert(!empty( ml )); 1525 &m2r = & remove_last(ml); assert(!empty( ml )); 1526 &m3r = & remove_last(ml); assert(empty( ml )); 1527 &mxr = & remove_last(ml); assert(empty( ml )); 1528 1528 1529 1529 assert( &m1r == &m1 ); … … 1538 1538 // stack at front 1539 1539 1540 assert( isEmpty( ml ));1540 assert(empty( ml )); 1541 1541 1542 1542 insert_first(ml, m1); … … 1544 1544 insert_first(ml, m3); 1545 1545 1546 &m3r = & remove_first(ml); assert(! isEmpty( ml ));1547 &m2r = & remove_first(ml); assert(! isEmpty( ml ));1548 &m1r = & remove_first(ml); assert( isEmpty( ml ));1549 &mxr = & remove_first(ml); assert( isEmpty( ml ));1546 &m3r = & remove_first(ml); assert(!empty( ml )); 1547 &m2r = & remove_first(ml); assert(!empty( ml )); 1548 &m1r = & remove_first(ml); assert(empty( ml )); 1549 &mxr = & remove_first(ml); assert(empty( ml )); 1550 1550 1551 1551 assert( &m1r == &m1 ); … … 1560 1560 // stack at back 1561 1561 1562 assert( isEmpty( ml ));1562 assert(empty( ml )); 1563 1563 1564 1564 insert_last(ml, m1); … … 1566 1566 insert_last(ml, m3); 1567 1567 1568 &m3r = & remove_last(ml); assert(! isEmpty( ml ));1569 &m2r = & remove_last(ml); assert(! isEmpty( ml ));1570 &m1r = & remove_last(ml); assert( isEmpty( ml ));1571 &mxr = & remove_last(ml); assert( isEmpty( ml ));1568 &m3r = & remove_last(ml); assert(!empty( ml )); 1569 &m2r = & remove_last(ml); assert(!empty( ml )); 1570 &m1r = & remove_last(ml); assert(empty( ml )); 1571 &mxr = & remove_last(ml); assert(empty( ml )); 1572 1572 1573 1573 assert( &m1r == &m1 ); … … 1593 1593 1594 1594 insert_before( iter( ml ), m1 ); 1595 assert( ! isEmpty( ml ) );1595 assert( !empty( ml ) ); 1596 1596 1597 1597 mary & mlfirst = first( ml );
Note:
See TracChangeset
for help on using the changeset viewer.