00001 //-*-c++-*- 00002 // ==================================================================== 00003 // ==================================================================== 00004 // 00005 // Module: bb_node_set.h 00006 // $Revision: 1.1.1.1 $ 00007 // $Date: 2005/10/21 19:00:00 $ 00008 // $Author: marcel $ 00009 // $Source: /proj/osprey/CVS/open64/osprey1.0/be/opt/bb_node_set.h,v $ 00010 // 00011 // ==================================================================== 00012 // 00013 // Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved. 00014 // 00015 // This program is free software; you can redistribute it and/or modify 00016 // it under the terms of version 2 of the GNU General Public License as 00017 // published by the Free Software Foundation. 00018 // 00019 // This program is distributed in the hope that it would be useful, but 00020 // WITHOUT ANY WARRANTY; without even the implied warranty of 00021 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00022 // 00023 // Further, this software is distributed without any warranty that it 00024 // is free of the rightful claim of any third person regarding 00025 // infringement or the like. Any license provided herein, whether 00026 // implied or otherwise, applies only to this software file. Patent 00027 // licenses, if any, provided herein do not apply to combinations of 00028 // this program with other software, or any other product whatsoever. 00029 // 00030 // You should have received a copy of the GNU General Public License 00031 // along with this program; if not, write the Free Software Foundation, 00032 // Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. 00033 // 00034 // Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 00035 // Mountain View, CA 94043, or: 00036 // 00037 // http://www.sgi.com 00038 // 00039 // For further information regarding this notice, see: 00040 // 00041 // http://oss.sgi.com/projects/GenInfo/NoticeExplan 00042 // 00043 // ==================================================================== 00044 // 00045 // Description: 00046 // 00047 // This package implements sets of BB_NODE*'s. These can be 00048 // manipulated with a fairly complete repertoire of set functions. 00049 // The sets are represented with bit strings for efficiency of both 00050 // space and run time. The vector that represents these sets is 00051 // grown as necessary to accommodate the results of the various 00052 // operations. In spite of this, the client of the package retains 00053 // control over storage allocation by providing memory allocation 00054 // pools (MEM_POOLs). The representations are never automatically 00055 // trimmed, so that the representation of any given bit set will be 00056 // large enough to hold the element with the greatest number that it 00057 // ever held. 00058 // 00059 // 00060 // 00061 // Destructive Operations Conventions 00062 // ================================== 00063 // 00064 // 00065 // The BB_NODE_SET class provides methods that work either on the 00066 // given instance, or can create and return new instances of a 00067 // set. Those that work through side-effects on the given instance 00068 // are considered "destructive" operations, and all such methods end 00069 // with the letter D. These methods still return the given instance 00070 // so expressions may be built up. For now, destructive operations 00071 // only expand storage, and never shrink it. 00072 // 00073 // 00074 // 00075 // Storage Allocation 00076 // ================== 00077 // 00078 // 00079 // The client of this package has full control over storage 00080 // allocation for BB_NODE_SET's. This is achieved by passing storage 00081 // allocation pools (MEM_POOLs) to the functions that may need to use 00082 // them. 00083 // 00084 // 00085 // 00086 // Types 00087 // ===== 00088 // 00089 // 00090 // CLASS BB_NODE_SET 00091 // 00092 // TYPE BB_NODE* 00093 // 00094 // This is the type of an element of a BB_NODE_SET. 00095 // 00096 // 00097 // 00098 // Constructors, Clearing, and Freeing 00099 // =============================== 00100 // 00101 // 00102 // BB_NODE_SET( 00103 // BS_ELT size, 00104 // const CFG *cfgraph, 00105 // MEM_POOL *pool, 00106 // BBNS_ACTION action 00107 // ) 00108 // 00109 // Creates an instance of a set, that can hold any BB_NODE with 00110 // an Id() in the range 0..size-1. 'size' must be non-negative. 00111 // The 'cfgraph' provides the mechanism to get from an integral 00112 // value back to a BB_NODE *. 00113 // The memory pool is where the memory for the bitset will be 00114 // allocated. 00115 // 'action' is one of: 00116 // BBNS_EMPTY : Clear the set on creation 00117 // BBNS_UNIVERSE : Fill the set on creation 00118 // BBNS_DONT_CARE: Leave the set uninitialized (caller should make 00119 // sure he will initialize it 00120 // 00121 // 00122 // BB_NODE_SET( 00123 // BS_ELT low, 00124 // BS_ELT high, 00125 // const CFG *cfgraph, 00126 // MEM_POOL *pool 00127 // ) 00128 // 00129 // Creates an instance of a set with members low..high 00130 // 00131 // 00132 // BB_NODE_SET( 00133 // const BB_NODE *bb, 00134 // const CFG *cfgraph, 00135 // MEM_POOL *pool 00136 // ) 00137 // 00138 // Creates an instance of a set with the sole member being 'bb' 00139 // 00140 // 00141 // BB_NODE_SET *ClearD() 00142 // 00143 // Destructive clear operation. After this 'set' will be empty. 00144 // However, this does not change the allocated size of the set 00145 // (it will still be able to contain the same members that it 00146 // could before it was cleared without expansion.) 00147 // 00148 // 00149 // BB_NODE_SET *RangeD( 00150 // BS_ELT low, 00151 // BS_ELT high, 00152 // ) 00153 // 00154 // Returns a set whose members are the BBs with Id() values of the 00155 // numbers 'low' ... 'high'. Both 'low' and the size of the 00156 // range must be nonnegative or an error is caused. I.e., 'low' 00157 // >= 0 and ('high' - 'low' + 1) >= 0. Note that 'high' may be 00158 // -1 if 'low' is 0. 00159 // 00160 // 00161 // BB_NODE_SET *SingletonD( 00162 // BB_NODE* element, 00163 // ) 00164 // 00165 // Returns a set with 'element' as its sole member. 00166 // 00167 // 00168 // BB_NODE_SET *UniverseD( 00169 // BS_ELT size, 00170 // ) 00171 // 00172 // Returns a set containing the BBs with Id() values of the numbers 00173 // 0...'size' - 1. 'Size' must be nonnegative or an error is 00174 // caused. 00175 // 00176 // 00177 // 00178 // Copying 00179 // ======= 00180 // 00181 // 00182 // BB_NODE_SET *Copy( 00183 // MEM_POOL *pool 00184 // ) 00185 // 00186 // Creates a new instance of the given set, but allocated from 00187 // a different memory pool. 00188 // 00189 // BB_NODE_SET *CopyD( 00190 // BB_NODE_SET *set2, 00191 // ) 00192 // 00193 // The given instance's set becomes an exact copy of set2. 00194 // 00195 // 00196 // Set Operations 00197 // ============== 00198 // 00199 // 00200 // BB_NODE* Choose() 00201 // 00202 // Returns some element of 'set', if 'set' is nonempty. Else 00203 // returns BB_NODE_SET_CHOOSE_FAILURE. In fact, this is defined so 00204 // that it always returns the least element of the set. 00205 // 00206 // 00207 // BB_NODE* Choose_Next( 00208 // BB_NODE* x 00209 // ) 00210 // 00211 // Returns the "next" element of 'set', starting after 'x', if 00212 // 'set' is nonempty. Else returns BB_NODE_SET_CHOOSE_FAILURE. 00213 // This is used for looping over the elements of a set. 00214 // 00215 // 00216 // BB_NODE* Choose_Range( 00217 // BS_ELT low, 00218 // BS_ELT high 00219 // ) 00220 // 00221 // Returns some element of 'set' whose Id() value is in the 00222 // range low..high if there is one. Else returns 00223 // BB_NODE_SET_CHOOSE_FAILURE. Both 'low' and the size of the 00224 // range must be nonnegative or an error is caused. 00225 // I.e., 'low' >= 0 and ('high' - 'low' + 1) >= 0. Note that 00226 // 'high' may be -1 if 'low' is 0. As with the Choose function, 00227 // always returns the least element of the set that's in range. 00228 // 00229 // 00230 // BB_NODE_SET *Difference( 00231 // BB_NODE_SET *set2, 00232 // MEM_POOL *pool 00233 // ) 00234 // 00235 // Creates a new instance and returns the given set with any 00236 // elements from set2 removed. 00237 // 00238 // BB_NODE_SET *DifferenceD( 00239 // BB_NODE_SET *set2 00240 // ) 00241 // 00242 // Returns the given set with any elements from set2 removed. 00243 // 00244 // 00245 // BB_NODE_SET *Difference1( 00246 // BB_NODE* x, 00247 // MEM_POOL *pool 00248 // ) 00249 // 00250 // Creates a new instance and returns the given set with element 00251 // x removed. 00252 // 00253 // BB_NODE_SET *Difference1D( 00254 // BB_NODE* x 00255 // ) 00256 // 00257 // Removes the element x from the set. 00258 // 00259 // 00260 // BB_NODE_SET *Intersection( 00261 // BB_NODE_SET *set2, 00262 // MEM_POOL *pool 00263 // ) 00264 // 00265 // Creates a new instance, allocated from pool, and returns the 00266 // intersection with 'set2'. 00267 // 00268 // BB_NODE_SET *IntersectionD( 00269 // BB_NODE_SET *set2 00270 // ) 00271 // 00272 // Intersects with set2. 00273 // 00274 // 00275 // BB_NODE_SET *Union( 00276 // BB_NODE_SET *set2, 00277 // MEM_POOL *pool 00278 // ) 00279 // Creates a new instance, allocated from pool, and returns the 00280 // union with 'set2'. 00281 // 00282 // BB_NODE_SET *UnionD( 00283 // BB_NODE_SET *set2, 00284 // ) 00285 // 00286 // Unions with set2. 00287 // 00288 // 00289 // BB_NODE_SET *Union1( 00290 // BB_NODE* x, 00291 // MEM_POOL *pool 00292 // ) 00293 // 00294 // Creates a new instance, allocated from pool, and returns the 00295 // set with element x added. 00296 // 00297 // BB_NODE_SET *Union1D( 00298 // BB_NODE* x, 00299 // ) 00300 // 00301 // Adds element x to the set. 00302 // 00303 // BB_NODE_SET *Union1D( 00304 // IDTYPE* id, 00305 // ) 00306 // 00307 // Adds BB_NODE with 'id' (say Id() or Dom_dfs_id()) to the set. 00308 // 00309 // size_t BB_NODE_SET Size() 00310 // 00311 // Returns the cardinality (population count) of the set. 00312 // 00313 // size_t BB_NODE_SET Alloc_size() 00314 // 00315 // Returns the number of bytes used to allocate the set. 00316 // 00317 // 00318 // Testing Sets 00319 // ============ 00320 // 00321 // 00322 // BOOL ContainsP( 00323 // BB_NODE_SET *set2 00324 // ) 00325 // 00326 // Returns TRUE iff every element of 'set2' is in the set. Else 00327 // FALSE. 00328 // 00329 // 00330 // BOOL EmptyP() 00331 // 00332 // Returns TRUE iff the is empty. Else FALSE. 00333 // 00334 // 00335 // BOOL EqualP( 00336 // BB_NODE_SET *set2 00337 // ) 00338 // 00339 // Returns TRUE iff the set has exactly the same members as 00340 // 'set2'. Else FALSE. 00341 // 00342 // 00343 // BOOL IntersectsP( 00344 // BB_NODE_SET *set2 00345 // ) 00346 // 00347 // Returns TRUE iff the set and 'set2' have at least one member in 00348 // common. Else FALSE. 00349 // 00350 // 00351 // BOOL MemberP( 00352 // BB_NODE* x 00353 // ) 00354 // 00355 // BOOL MemberP( 00356 // IDTYPE id 00357 // ) 00358 // 00359 // Returns TRUE iff 'x' or 'id' is a member of the set. Else FALSE. 00360 // 00361 // 00362 // Looping Over Members 00363 // ==================== 00364 // 00365 // 00366 // This is done using Choose and Choose_Next. Here is an example: 00367 // 00368 // BB_NODE* x; 00369 // BB_NODE_SET *set; 00370 // 00371 // for ( x = set->Choose(); 00372 // x != BB_NODE_SET_CHOOSE_FAILURE; 00373 // x = set->Choose_Next( x ) ) 00374 // { 00375 // x is a member of the set 00376 // } 00377 // 00378 // 00379 // Handling Intersections Effeciently 00380 // =================================== 00381 // 00382 // 00383 // Often, once wants to perform operations on the intersection of two 00384 // sets without having to create the intersection. This can be thought 00385 // of as an "operation with a mask". Anyway, a set of functions is 00386 // provided to support this: 00387 // 00388 // 00389 // BOOL Intersection_MemberP( 00390 // BB_NODE_SET *set2, 00391 // BB_NODE* x 00392 // ) 00393 // 00394 // Returns TRUE iff 'x' is a member of the intersection of the set 00395 // and 'set2' . Else FALSE. 00396 // 00397 // 00398 // BB_NODE* Intersection_Choose( 00399 // BB_NODE_SET *set2 00400 // ) 00401 // 00402 // Returns some element of of the intersection of the set and 00403 // 'set2', if the intersection is nonempty. Else returns 00404 // BB_NODE_SET_CHOOSE_FAILURE. In fact, this is defined so that 00405 // it always returns the least element of the set. 00406 // 00407 // 00408 // BB_NODE* Intersection_Choose_Next( 00409 // BB_NODE_SET *set2, 00410 // BB_NODE* x 00411 // ) 00412 // 00413 // Returns the "next" element of the intersection of the set and 00414 // 'set2', starting after 'x', if there is such a member. Else 00415 // returns BB_NODE_SET_CHOOSE_FAILURE. This is very useful for 00416 // looping over the elements of a set intersection. 00417 // 00418 // 00419 // Printing Sets 00420 // ============= 00421 // 00422 // 00423 // void Print( 00424 // FILE *f 00425 // ) 00426 // 00427 // Prints the set on 'f'. The type FILE is as defined in stdio.h. 00428 // 00429 // ==================================================================== 00430 // ==================================================================== 00431 00432 #ifndef bb_node_set_INCLUDED 00433 #define bb_node_set_INCLUDED "bb_node_set.h" 00434 #ifdef _KEEP_RCS_ID 00435 static char *bb_node_set_rcs_id = bb_node_set_INCLUDED"$Revision$"; 00436 #endif /* _KEEP_RCS_ID */ 00437 00438 #include "mempool.h" // our clients should probably include this 00439 #include "bitset.h" // our clients do not need to know about it 00440 #include "opt_bb.h" 00441 #include "opt_cfg.h" 00442 #include "erglob.h" 00443 00444 #define BB_NODE_SET_CHOOSE_FAILURE ((BB_NODE*)BS_CHOOSE_FAILURE) 00445 00446 // action to use in constructor to decide how the bitset should be 00447 // initialized 00448 typedef enum { 00449 BBNS_EMPTY, // clear set when creating 00450 BBNS_UNIVERSE, // fill set when creating 00451 BBNS_DONT_CARE, // leave set uninitialized 00452 } BBNS_ACTION; 00453 00454 class BB_NODE_SET { 00455 private: 00456 BS *bs; // the actual bitset 00457 const CFG *cfg; // control-flow graph to get index => bb_node 00458 MEM_POOL *mempool; // memory pool to use as default 00459 00460 // constructor to override default (never used for this class) 00461 BB_NODE_SET(void) {} 00462 BB_NODE_SET(const BB_NODE_SET&); 00463 BB_NODE_SET& operator = (const BB_NODE_SET&); 00464 00465 // constructor to create set with no BS 00466 BB_NODE_SET( const CFG *cfgraph, MEM_POOL *pool ) 00467 { mempool = pool; 00468 cfg = cfgraph; 00469 } 00470 00471 // function to convert from cfg,int to bb_node 00472 BB_NODE *id2bb( BS_ELT id ) const 00473 { return id != BS_CHOOSE_FAILURE ? 00474 cfg->Get_bb(id) : 00475 BB_NODE_SET_CHOOSE_FAILURE; 00476 } 00477 00478 public: 00479 // constructor to create empty set with given size 00480 BB_NODE_SET( BS_ELT size, const CFG *cfgraph, MEM_POOL *pool, 00481 BBNS_ACTION action ) 00482 { mempool = pool; 00483 cfg = cfgraph; 00484 switch ( action ) { 00485 case BBNS_EMPTY: 00486 bs = BS_Create_Empty( size, pool ); 00487 break; 00488 case BBNS_UNIVERSE: 00489 bs = BS_Universe( size, pool ); 00490 break; 00491 case BBNS_DONT_CARE: 00492 bs = BS_Create( size, pool ); 00493 break; 00494 default: 00495 ErrMsg( EC_Misc_Int, "BB_NODE_SET: action", 00496 (INT) action ); 00497 break; 00498 } 00499 } 00500 00501 // constructor to create set with elements low..high set 00502 BB_NODE_SET( BS_ELT low, BS_ELT high, 00503 const CFG *cfgraph, MEM_POOL *pool ) 00504 { mempool = pool; 00505 cfg = cfgraph; 00506 bs = BS_Range( low, high, pool ); 00507 } 00508 00509 // constructor to create set with single element bb included 00510 BB_NODE_SET( const BB_NODE *bb, const CFG *cfgraph, MEM_POOL *pool ) 00511 { mempool = pool; 00512 cfg = cfgraph; 00513 bs = BS_Singleton( bb->Id(), pool ); 00514 } 00515 00516 // destructor 00517 ~BB_NODE_SET(void) {} 00518 00519 BS *Bs(void) const { return bs; } 00520 00521 const CFG *Cfg(void) const { return cfg; } 00522 00523 BB_NODE_SET *ClearD( void ) 00524 { bs = BS_ClearD(bs); 00525 return this; 00526 } 00527 00528 BB_NODE_SET *RangeD( BS_ELT low, BS_ELT high ) 00529 { bs = BS_RangeD( bs, low, high, mempool ); 00530 return this; 00531 } 00532 00533 BB_NODE_SET *SingletonD( const BB_NODE *bb ) 00534 { bs = BS_SingletonD( bs, bb->Id(), mempool ); 00535 return this; 00536 } 00537 00538 BB_NODE_SET *UniverseD( BS_ELT size ) 00539 { bs = BS_UniverseD( bs, size, mempool ); 00540 return this; 00541 } 00542 00543 BB_NODE_SET *Copy( MEM_POOL *pool ) 00544 { BB_NODE_SET *new1 = CXX_NEW(BB_NODE_SET(cfg,pool),pool); 00545 new1->bs = BS_Copy( bs, pool ); 00546 return new1; 00547 } 00548 00549 BB_NODE_SET *CopyD( const BB_NODE_SET *bbns ) 00550 { bs = BS_CopyD( bs, bbns->bs, mempool ); 00551 return this; 00552 } 00553 00554 00555 // To be obsolete. Replace by iterators. 00556 00557 BB_NODE *Choose( void ) const 00558 { return id2bb(BS_Choose(bs)); } 00559 00560 BB_NODE *Intersection_Choose( const BB_NODE_SET *bbns ) const 00561 { return id2bb(BS_Intersection_Choose(bs,bbns->bs)); } 00562 00563 BB_NODE *Choose_Next( const BB_NODE *bb ) const 00564 { return id2bb(BS_Choose_Next(bs,bb->Id())); } 00565 00566 BB_NODE *Intersection_Choose_Next( const BB_NODE_SET *bbns, 00567 const BB_NODE *bb ) const 00568 { return id2bb( 00569 BS_Intersection_Choose_Next(bs,bbns->bs,bb->Id()) ); 00570 } 00571 00572 BB_NODE *Choose_Range( BS_ELT low, BS_ELT high ) const 00573 { return id2bb(BS_Choose_Range(bs,low,high)); } 00574 00575 // 00576 00577 BB_NODE_SET *Difference( const BB_NODE_SET *bbns, MEM_POOL *pool ) 00578 { BB_NODE_SET *new1 = CXX_NEW(BB_NODE_SET(cfg,pool),pool); 00579 new1->bs = BS_Difference( bs, bbns->bs, pool ); 00580 return new1; 00581 } 00582 00583 BB_NODE_SET *DifferenceD( const BB_NODE_SET *bbns ) 00584 { bs = BS_DifferenceD( bs, bbns->bs ); 00585 return this; 00586 } 00587 00588 BB_NODE_SET *Difference1( const BB_NODE *bb, MEM_POOL *pool ) 00589 { BB_NODE_SET *new1 = CXX_NEW(BB_NODE_SET(cfg,pool),pool); 00590 new1->bs = BS_Difference1( bs, bb->Id(), pool ); 00591 return new1; 00592 } 00593 00594 BB_NODE_SET *Difference1D( const BB_NODE *bb ) 00595 { bs = BS_Difference1D( bs, bb->Id() ); 00596 return this; 00597 } 00598 00599 BB_NODE_SET *Intersection( const BB_NODE_SET *bbns, MEM_POOL *pool ) 00600 { BB_NODE_SET *new1 = CXX_NEW(BB_NODE_SET(cfg,pool),pool); 00601 new1->bs = BS_Intersection( bs, bbns->bs, pool ); 00602 return new1; 00603 } 00604 00605 BB_NODE_SET *IntersectionD( const BB_NODE_SET *bbns ) 00606 { bs = BS_IntersectionD( bs, bbns->bs ); 00607 return this; 00608 } 00609 00610 BS_ELT Size( void ) const 00611 { return BS_Size(bs); } 00612 00613 BS_ELT Alloc_size( void ) const 00614 { return BS_Alloc_Size(bs); } 00615 00616 BB_NODE_SET *Union( const BB_NODE_SET *bbns, MEM_POOL *pool ) 00617 { BB_NODE_SET *new1 = CXX_NEW(BB_NODE_SET(cfg,pool),pool); 00618 new1->bs = BS_Union( bs, bbns->bs, pool ); 00619 return new1; 00620 } 00621 00622 BB_NODE_SET *UnionD( const BB_NODE_SET *bbns ) 00623 { bs = BS_UnionD( bs, bbns->bs, mempool ); 00624 return this; 00625 } 00626 00627 BB_NODE_SET *Union1( const BB_NODE *bb, MEM_POOL *pool ) 00628 { BB_NODE_SET *new1 = CXX_NEW(BB_NODE_SET(cfg,pool),pool); 00629 new1->bs = BS_Union1( bs, bb->Id(), pool ); 00630 return new1; 00631 } 00632 00633 BB_NODE_SET *Union1D( const BB_NODE *bb ) 00634 { bs = BS_Union1D( bs, bb->Id(), mempool ); 00635 return this; 00636 } 00637 00638 BB_NODE_SET *Union1D( const IDTYPE id ) 00639 { bs = BS_Union1D( bs, id, mempool ); 00640 return this; 00641 } 00642 00643 BOOL ContainsP( const BB_NODE_SET *bbns ) const 00644 { return BS_ContainsP( bs, bbns->bs ); } 00645 00646 BOOL EmptyP( void ) const 00647 { return BS_EmptyP( bs ); } 00648 00649 BOOL EqualP( const BB_NODE_SET *bbns ) const 00650 { return BS_EqualP( bs, bbns->bs ); } 00651 00652 BOOL IntersectsP( const BB_NODE_SET *bbns ) const 00653 { return BS_IntersectsP( bs, bbns->bs ); } 00654 00655 BOOL MemberP( const BB_NODE *bb ) const 00656 { return BS_MemberP( bs, bb->Id() ); } 00657 00658 BOOL MemberP( const IDTYPE id ) const 00659 { return BS_MemberP( bs, id ); } 00660 00661 BOOL Intersection_MemberP( const BB_NODE_SET *bbns, const BB_NODE *bb) const 00662 { return BS_Intersection_MemberP(bs,bbns->bs,bb->Id());} 00663 00664 void Print( FILE *fp=stderr ) const 00665 { fprintf(fp, "%lld ", (INT64)BS_Alloc_Size(bs)); BS_Print( bs, fp ); } 00666 00667 }; // end BB_NODE_SET 00668 00669 00670 class BB_NODE_SET_ITER { 00671 private: 00672 BS *bs; // pointer to the bs 00673 BS_ELT cur; 00674 const CFG *cfg; 00675 BB_NODE_SET_ITER(const BB_NODE_SET_ITER&); 00676 BB_NODE_SET_ITER& operator = (const BB_NODE_SET_ITER&); 00677 00678 public: 00679 BB_NODE_SET_ITER(void) { bs = NULL; } 00680 ~BB_NODE_SET_ITER(void) {} 00681 void Init(BB_NODE_SET *bns) { bs = bns->Bs(); cfg = bns->Cfg(); } 00682 00683 BB_NODE *Id2bb(const BS_ELT id) const 00684 { return id != BS_CHOOSE_FAILURE ? cfg->Get_bb(id) : NULL; } 00685 00686 BS_ELT First(void) { return cur = BS_Choose(bs); } 00687 BS_ELT Next(void) { return cur = BS_Choose_Next(bs, cur); } 00688 BOOL Is_Empty(void) const { return (cur == BS_CHOOSE_FAILURE); } 00689 BB_NODE *First_elem(void) { return Id2bb(First()); } 00690 BB_NODE *Next_elem(void) { return Id2bb(Next()); } 00691 }; 00692 00693 00694 #endif // bb_node_set_INCLUDED
1.5.6