1 #ifndef _ITAPS_iBase 2 #define _ITAPS_iBase 3 4 /***************************************************************************//** 5 * \ingroup VersionNumbers 6 * \brief Compile time version number digits 7 * 8 * iBase maintains a major, minor and patch digit in its version number. 9 * Technically speaking, there is not much practical value in patch digit 10 * for an interface specification. A patch release is typically only used 11 * for bug fix releases. Although it is rare, sometimes a bug fix 12 * necessitates an API change. So, we define a patch digit for iBase. 13 * 14 * Although each interface in ITAPS has been designed to support its own 15 * unique version numbers, apart from other ITAPS interfaces, as currently 16 * used, we require all ITAPS interfaces to use the same ITAPS-wide version 17 * number derived from the version number defined by these three digits. 18 ******************************************************************************/ 19 #define IBASE_VERSION_MAJOR 1 20 #define IBASE_VERSION_MINOR 4 21 #define IBASE_VERSION_PATCH 1 22 23 /***************************************************************************//** 24 * \ingroup VersionNumbers 25 * \brief Version Comparison 26 * 27 * Evaluates to true at CPP time if the version of iBase currently being 28 * compiled is greater than or equal to the version specified. 29 ******************************************************************************/ 30 #define IBASE_VERSION_GE(Maj,Min,Pat) \ 31 (((IBASE_VERSION_MAJOR==(Maj)) && (IBASE_VERSION_MINOR==(Min)) && (IBASE_VERSION_PATCH>=(Pat))) || \ 32 ((IBASE_VERSION_MAJOR==(Maj)) && (IBASE_VERSION_MINOR>(Min))) || \ 33 (IBASE_VERSION_MAJOR>(Maj))) 34 35 /***************************************************************************//** 36 * \ingroup VersionNumbers 37 * \brief Compose compile-time string represention of the version number 38 ******************************************************************************/ 39 #define IBASE_VERSION_STRING___(I,X,Y,Z) #I "_Version_" #X "." #Y "." #Z 40 #define IBASE_VERSION_STRING__(I,X,Y,Z) IBASE_VERSION_STRING___(I,X,Y,Z) 41 #define IBASE_VERSION_STRING_(I) IBASE_VERSION_STRING__(I,IBASE_VERSION_MAJOR,IBASE_VERSION_MINOR,IBASE_VERSION_PATCH) 42 #define IBASE_VERSION_STRING IBASE_VERSION_STRING_(iBase) 43 44 /***************************************************************************//** 45 * \ingroup VersionNumbers 46 * \brief Compose compile-time symbol name derived from the version number. 47 ******************************************************************************/ 48 #define IBASE_VERSION_TAG__(I,X,Y,Z) I##_Version_##X##_##Y##_##Z 49 #define IBASE_VERSION_TAG_(I,X,Y,Z) IBASE_VERSION_TAG__(I,X,Y,Z) 50 #define IBASE_VERSION_TAG(I) IBASE_VERSION_TAG_(I,IBASE_VERSION_MAJOR,IBASE_VERSION_MINOR,IBASE_VERSION_PATCH) 51 52 /***************************************************************************//** 53 * \ingroup VersionNumbers 54 * \brief ITAPS-wide (across all ITAPS APIs) version handling 55 ******************************************************************************/ 56 #define ITAPS_VERSION_MAJOR IBASE_VERSION_MAJOR 57 #define ITAPS_VERSION_MINOR IBASE_VERSION_MINOR 58 #define ITAPS_VERSION_PATCH IBASE_VERSION_PATCH 59 #define ITAPS_VERSION_GE(Maj,Min,Pat) IBASE_VERSION_GE(Maj,Min,Pat) 60 #define ITAPS_VERSION_STRING_(I) IBASE_VERSION_STRING_(I) 61 #define ITAPS_VERSION_STRING ITAPS_VERSION_STRING_(ITAPS) 62 #define ITAPS_VERSION_TAG_(I) IBASE_VERSION_TAG(I) 63 #define ITAPS_VERSION_TAG ITAPS_VERSION_TAG_(I) 64 65 /***************************************************************************//** 66 * \defgroup EnumIterators Enum-Iterators 67 * \ingroup iBase 68 * \brief Convenience macros for iterating over all possible values in an enum 69 * 70 * These convenience macros are provided to facilitate iterating over all 71 * possible values in an enumerated type. To use these macros, for example... 72 * \code 73 * for (iBase_EntityType i = IBASE_MINENUM(iBase_EntityType); 74 * i <= IBASE_MAXENUM(iBase_EntityType); 75 * IBASE_INCENUM(i,iBase_EntityType)) 76 * { 77 * } 78 * \endcode 79 * Be aware that some enumerated types include a <em>wild card</em> often used 80 * in queries to represent all possible values and you may or may not want to 81 * include such a value in your iteration. 82 ******************************************************************************/ 83 84 /***************************************************************************//** 85 * \ingroup EnumIterators 86 * @{ 87 ******************************************************************************/ 88 #define IBASE_MINENUM(enumName) enumName ## _MIN 89 #define IBASE_MAXENUM(enumName) enumName ## _MAX 90 #define IBASE_NUMENUM(enumName) ((int)IBASE_MAXENUM(enumName) - (int)IBASE_MINENUM(enumName) + 1) 91 #define IBASE_INCENUM(enumName,I) (I = (enum enumName)((int)I+1)) 92 /** @} */ 93 94 #ifdef __cplusplus 95 extern "C" { 96 #endif 97 98 typedef void* iBase_Instance; 99 typedef struct iBase_EntityHandle_Private* iBase_EntityHandle; 100 typedef struct iBase_EntitySetHandle_Private* iBase_EntitySetHandle; 101 typedef struct iBase_TagHandle_Private* iBase_TagHandle; 102 typedef struct iBase_EntityIterator_Private* iBase_EntityIterator; 103 typedef struct iBase_EntityArrIterator_Private* iBase_EntityArrIterator; 104 105 enum iBase_EntityType { 106 iBase_EntityType_MIN = 0, 107 /**< facilitates iteration over all values */ 108 iBase_VERTEX = iBase_EntityType_MIN, 109 /**< A topological dimension 0 entity */ 110 iBase_EDGE, 111 /**< A topological dimension 1 entity */ 112 iBase_FACE, 113 /**< A topological dimension 2 entity */ 114 iBase_REGION, 115 /**< A topological dimension 3 entity */ 116 iBase_ALL_TYPES, 117 /**< used only in queries to request information about all types */ 118 iBase_EntityType_MAX = iBase_ALL_TYPES 119 /**< facilitates iteration over all values */ 120 }; 121 122 enum iBase_AdjacencyCost { 123 iBase_AdjacencyCost_MIN = 0, 124 /**< facilitates iteration over all values */ 125 iBase_UNAVAILABLE = iBase_AdjacencyCost_MIN, 126 /**< Adjacency information not supported */ 127 iBase_ALL_ORDER_1, 128 /**< No more than local mesh traversal required (i!=j) */ 129 iBase_ALL_ORDER_LOGN, 130 /**< Global tree search (i!=j) */ 131 iBase_ALL_ORDER_N, 132 /**< Global exhaustive search (i!=j) */ 133 iBase_SOME_ORDER_1, 134 /**< Only some adjacency info, local (i!=j) */ 135 iBase_SOME_ORDER_LOGN, 136 /**< Only some adjacency info, tree (i!=j) */ 137 iBase_SOME_ORDER_N, 138 /**< Only some adjacency info, exhaustive (i!=j) */ 139 iBase_AVAILABLE, 140 /**< ALL (intermediate) entities available. (i==j) */ 141 iBase_AdjacencyCost_MAX = iBase_AVAILABLE 142 /**< facilitates iteration over all values */ 143 }; 144 145 enum iBase_CreationStatus { 146 iBase_CreationStatus_MIN = 0, 147 /**< facilitates iteration over all values */ 148 iBase_NEW = iBase_CreationStatus_MIN, 149 /**< The entity was newly created */ 150 iBase_ALREADY_EXISTED, 151 /**< The entity already existed and the handle for that 152 already existing handle was returned */ 153 iBase_CREATED_DUPLICATE, 154 /**< The entity already existed but a new, duplicate entity was 155 nevertheless created */ 156 iBase_CREATION_FAILED, 157 /**< Creation of the entity did not succeed */ 158 iBase_CreationStatus_MAX = iBase_CREATION_FAILED 159 /**< facilitates iteration over all values */ 160 }; 161 162 enum iBase_ErrorType { 163 iBase_ErrorType_MIN = 0, 164 /**< facilitates iteration over all values */ 165 iBase_SUCCESS = iBase_ErrorType_MIN, 166 iBase_MESH_ALREADY_LOADED, 167 iBase_FILE_NOT_FOUND, 168 iBase_FILE_WRITE_ERROR, 169 iBase_NIL_ARRAY, 170 iBase_BAD_ARRAY_SIZE, 171 iBase_BAD_ARRAY_DIMENSION, 172 iBase_INVALID_ENTITY_HANDLE, 173 iBase_INVALID_ENTITY_COUNT, 174 iBase_INVALID_ENTITY_TYPE, 175 iBase_INVALID_ENTITY_TOPOLOGY, 176 iBase_BAD_TYPE_AND_TOPO, 177 iBase_ENTITY_CREATION_ERROR, 178 iBase_INVALID_TAG_HANDLE, 179 iBase_TAG_NOT_FOUND, 180 iBase_TAG_ALREADY_EXISTS, 181 iBase_TAG_IN_USE, 182 iBase_INVALID_ENTITYSET_HANDLE, 183 iBase_INVALID_ITERATOR_HANDLE, 184 iBase_INVALID_ARGUMENT, 185 iBase_MEMORY_ALLOCATION_FAILED, 186 iBase_NOT_SUPPORTED, 187 iBase_FAILURE, 188 iBase_ErrorType_MAX = iBase_FAILURE 189 /**< facilitates iteration over all values */ 190 }; 191 192 /***************************************************************************//** 193 * \details 194 * Many of the functions in iMesh can return arrays of tuples; that is, arrays 195 * of multi-valued type. For example, the function iMesh_getVtxArrCoords, 196 * returns an array of xyz coordinate 3-tuples (or, perhaps for geometrically 197 * 2D meshes, xy 2-tuples). In these situations, there are multiple ways the 198 * data can be organized in memory. For example, it could be stored xyz,xyz,xyz 199 * or xxx...,yyy...,zzz.... These two different storage orders are referred 200 * to as INTERLEAVED and BLOCKED, respectively. For some functions in iMesh, 201 * the storage order is explicitly specified as an argument to the function. 202 * For other functions, the storage order is not explicitly specified. And, 203 * in these cases, it shall always be implicitly assumed to be INTERLEAVED. 204 * This fact will be mentioned in the documentation for each specific function 205 * where it applies. For example, in case of iMesh_getEntArrAdj, the returned 206 * array of adjacent entities is multi-valued in that it stores for each 207 * entity queried, all its adjacent entities. Such an array will be stored 208 * INTERLEAVED with all adjacent entities for the first entity in the query 209 * followed by all adjacent entities for the second entity in the query and 210 * so forth. 211 ******************************************************************************/ 212 enum iBase_StorageOrder { 213 iBase_StorageOrder_MIN = 0, 214 /**< facilitates iteration over all values */ 215 iBase_BLOCKED = iBase_StorageOrder_MIN, 216 /**< xxx...yyy...zzz... */ 217 iBase_INTERLEAVED, 218 /**< xyzxyzxyz... */ 219 iBase_StorageOrder_MAX = iBase_INTERLEAVED 220 /**< facilitates iteration over all values */ 221 }; 222 223 enum iBase_TagValueType { 224 iBase_TagValueType_MIN = 0, 225 /**< facilitates iteration over all values */ 226 iBase_BYTES = iBase_TagValueType_MIN, 227 /**< An opaque sequence of bytes, size always measured in bytes */ 228 iBase_INTEGER, 229 /**< A value of type \c int */ 230 iBase_DOUBLE, 231 /**< A value of type \c double */ 232 iBase_ENTITY_HANDLE, 233 /**< A value of type \c iBase_EntityHandle */ 234 iBase_ENTITY_SET_HANDLE, 235 /**< A value of type \c iBase_EntitySetHandle */ 236 iBase_TagValueType_MAX = iBase_ENTITY_SET_HANDLE 237 /**< facilitates iteration over all values */ 238 }; 239 240 /***************************************************************************//** 241 * \page ibase iBase: ITAPS Base Interface 242 ******************************************************************************/ 243 244 /***************************************************************************//** 245 * \defgroup iBase iBase 246 ******************************************************************************/ 247 248 /***************************************************************************//** 249 * \defgroup VersionNumbers Version Numbers 250 * \ingroup iBase 251 ******************************************************************************/ 252 253 /***************************************************************************//** 254 * \defgroup ErrorHandling Error Handling 255 * \ingroup iBase 256 ******************************************************************************/ 257 258 /***************************************************************************//** 259 * \defgroup Datatypes Datatypes 260 * \ingroup iBase 261 ******************************************************************************/ 262 263 /***************************************************************************//** 264 * \page The ITAPS Interfaces 265 * 266 * \subpage ibase 267 * 268 * \subpage imesh 269 * 270 * \subpage imeshp 271 * 272 * \subpage error 273 * 274 * \subpage trio 275 * 276 * \subpage strlen 277 * 278 * \subpage options 279 * 280 * \subpage numhops 281 * 282 * \subpage resilient 283 * 284 * \page error Error Handling 285 * 286 * With few exceptions, every iMesh function includes an output argument, 287 * 'int *err', which returns an error code indicating if the function call 288 * may have failed. If the value returned for the 'err' argument is NOT 289 * iBase_SUCCESS, the caller should NOT attempt to interpret (read the 290 * values in) any of the other return arguments of the call. While some 291 * implementations may actually return valid/useful results in other 292 * return arguments of a call that has failed, there is no guarentee that 293 * ALL implementations will do similarly and so depending on such behavior 294 * is neither portable nor safe. This is true even if the returned values 295 * are different from the values of the arguments before the call was 296 * made. 297 * 298 * \page trio Array pointer, allocated and occupied sizes argument trio 299 * 300 * Many of the functions in iMesh have arguments corresponding to lists of 301 * objects. In-type arguments for lists consist of a pointer to an array and 302 * a list size. Lists returned from functions are passed in three arguments, 303 * a pointer to the array representing the list, and pointers to the 304 * allocated and occupied lengths of the array. These three arguments are 305 * inout-type arguments, because they can be allocated by the application and 306 * passed into the interface to hold the results of the function. Lists 307 * which are pre-allocated must be large enough to hold the results of the 308 * function; if this is not the case, an error is generated. Otherwise, the 309 * occupied size is changed to the size output from the function. If a list 310 * argument is unallocated (the list pointer points to a NULL value) or if 311 * the incoming value of the allocated size is zero, the list storage will be 312 * allocated by the implementation. 313 * 314 * IN ALL CASES, MEMORY ALLOCATED BY ITAPS INTERFACE IMPLEMENTATIONS IS DONE 315 * USING THE C MALLOC FUNCTION, AND MUST BE DE-ALLOCATED USING THE C FREE 316 * FUNCTION. 317 * 318 * \page strlen String Length Arguments 319 * 320 * Many of the functions in iMesh involve passing a string and also the length 321 * of that string. How is the null character is handled? 322 * For users of the iMesh interface calling iMesh functions, it is optional 323 * as to whether or not to include the null character in computing the length 324 * of the string. So, for example, calling iMesh from a C program, users could 325 * pass strlen(my_string) or strlen(my_string)+1 as the length of the string. 326 * 327 * <em>Note to implementors</em>: However, it should be noted that the situation 328 * is different for implementers of the iMesh interface. In implementing an 329 * iMesh interface function, there can be no assumption that the string is 330 * indeed null terminated. The length argument the caller passes in may or may 331 * NOT include the null character and implementations must be coded to 332 * accommodate this. This requirement is primarily due to differences in how 333 * Fortran and C/C++ handle passing of strings as function arguments. 334 * Furthermore, because of the way Fortran clients pass strings (Fortran always 335 * passes the length of the string as declared in the source code), there 336 * may be trailing spaces in the string that need to be truncated. 337 * 338 * \page numhops Indirection in Set-Inclusion and Parent-Child structures 339 * 340 * Various functions to query entities, entity sets and parent or child sets 341 * as well as the numbers of these involve a num_hops argument. If the set 342 * upon which the query is originated is the root set, the num_hops argument 343 * is irrelevant and is ignored by the implementation. Otherwise, the num_hops 344 * argument represents the maximum number of levels of indirection employed in 345 * satisfying the query not including the originating set. For example, using 346 * value for num_hops of 0 (zero) in iMesh_getEntSets will return all the 347 * entity sets that are immediately contained in a given set. Likewise, a 348 * value for num_hops of 1 (one) will return all entity sets that are 349 * immediately contained in the given set plus all entity sets that 350 * are contained in those immediately contained sets (e.g. one level of 351 * indirection). Using a value of -1 for num_hops will return results for 352 * all possible levels of indirection. In other words, using a value of 353 * -1 for num_hops is equivalent to setting the maximum number of levels 354 * of indirection to infinity. 355 * 356 * \page options Option Strings 357 * 358 * A few of the functions in iMesh support arbitrary options passed as a 359 * character string, called an 'Option String'. The format of and handling 360 * of an Option String is as follows... 361 * 362 * 1. Option Strings are INsensitive to case. 363 * 364 * 2. Each option in an Option String is pre-pended with the implementation 365 * name followed by a special character called the separator character. 366 * 367 * 3. The separator is a colon, ':'. 368 * 369 * 4. Multiple options existing in a single Option String are separated by a 370 * special character called the delimiter character. 371 * 372 * 5. The delimiter character is a space, ' '. 373 * 374 * 6. The effect of multiple options in a single Option String is 375 * INsensitive to order of occurrence in the string. 376 * 377 * 7. By default, implementations silently ignore any options that 378 * do not match on the implementation name part (everything before 379 * the separator character). This way, a caller may included options 380 * in a single string intended for multiple different implementations. 381 * 382 * 8. Implementations may (or may not) warn or error for option strings 383 * that match on implementation name part but are found to be in error 384 * for other reasons the implementation decides. 385 * 386 * 9. Whenever either the separator character, ':', or delimiter character, 387 * ' ', need to appear in an option, they must be escaped with the 388 * backslash character, '\'. 389 * 390 * For example, consider the Options String 391 * 392 * "grummp:silant FMDB:TwoPhaseIO moab:mpiio_hints\ foo\:bar" 393 * 394 * In the above example, the space serves as the delimiter character 395 * between multiple options in the string. The colon serves as the 396 * implementation-name/option separator character. Because options are 397 * required to be insensitive to case, the caller is free to use case as a 398 * word separator as in 'TwoPhaseIO' and even in the implementation name, 399 * as in 'FMDB:', although 'fmdb:twophaseio' and 'fmdb:TWOPHASEIO' would 400 * all have the same effect. In the moab option, both the separator 401 * character and delimiter character appear in the option and so are 402 * pre-pended (e.g. escaped) with the backslash character. 403 404 * GRUMMP will silently ignore the FMDB: and moab: options because they do 405 * NOT match on the implementation name part. However, GRUMMP may 406 * optionally error out, or warn or silently ignore 'grummp:silant' (it was 407 * supposed to be spelled 'silent') as an invalid option. 408 * 409 * Note that iMesh itself currently does not define any options. In order 410 * to discover options a given implementation defines, users are directed 411 * to the developers of the respective implementations. 412 * 413 * \page resilient Resilient and Non-Resilient Iterators 414 * 415 * A resilient iterator is one that can deal with modifications to the container 416 * it is iterating over. 417 * 418 * A common concern about an iterator is how it behaves when the container 419 * over which it is iterating is modified. For example, in STL, iterators 420 * for std::set<> and std::map<> and std::list<> containers are guaranteed 421 * to <em>work</em> in the presence of modifications to the associated 422 * containers with one exception; they don't handle the case when the 423 * container member the iterator is currently pointed at is deleted. However, 424 * iterators for std::vector<> are not guaranteed to work under any kinds of 425 * modification. 426 * 427 * In the ITAPS interfaces, a <em>resilient</em> iterator is one that makes 428 * certain guarantees (described below) about how it behaves when the 429 * container being iterated is modified. On the other hand, a 430 * <em>non-resilient</em> is one that does not make such guarantees. 431 * 432 * In all cases, the <em>container</em> associated with an iterator in the 433 * ITAPS interfaces is an entity set of some sort. This is the only container 434 * type for which iterators are defined. 435 * 436 * Here, we characterize the behavior of iterators in the presence of 437 * container modifications. There are a number of (subtle) aspects to 438 * keep in mind. 439 * 440 * 1. There are set-type (<em>duplicate preventing</em>) sets and list-type 441 * (<em>order preserving</em>) sets and iterators behave differently for each. 442 * 443 * 2. Sets can have <em>set</em> members and <em>entity</em> members. However, 444 * iterators are currently defined to iterate over <em>only</em> the entity 445 * members. That said, the question arises as to whether modifications that 446 * involve only set members nonetheless <em>effect</em> iterator behavior. 447 * 448 * 3. There are array-type iterators that upon each step in the iteration 449 * return a whole array of entity member handles and single entity iterators 450 * that upon each step return just a single entity member handle. 451 * 452 * 4. The iterators support type/topology <em>filtering</em>. Iterators do not 453 * (always) strictly iterate over <em>all</em> entities in a set; just 454 * <em>all</em> entities matching the type/topology criteria. When 455 * type/topology specifies either all types or all topologies, then indeed 456 * the iterator will iterate over all entities. 457 * 458 * 5. There are add/remove operations that add/remove <em>entity members</em> or 459 * <em>set members</em> to a set. 460 * 461 * 6. There are create/delete operations that create and delete 462 * <em>entities</em> from the whole iMesh_Instance. 463 * 464 * 7. There are create/destroy operations that create and destroy 465 * <em>sets</em> from the whole interface instance. 466 * 467 * 8. There is the <em>root set</em> which is special and may have different 468 * iterator behavior than all other sets. By definition, the root set is a set-type 469 * (<em>duplicate prevent</em>) set. 470 * 471 * Modification means addition/removal and/or create/destroy and/or create/delete 472 * <em>after</em> iterator initialization. When we talk about 473 * <em>container modification</em> here, we are talking about any of the 474 * following operations. 475 * 476 * A. addition and removal of entity members 477 * \code 478 * void iMesh_rmvEntFromSet(iMesh_Instance instance, 479 * void iMesh_rmvEntArrFromSet(iMesh_Instance instance, 480 * void iMesh_addEntToSet(iMesh_Instance instance, 481 * void iMesh_addEntArrToSet(iMesh_Instance instance, 482 * \endcode 483 * B. addition and removal of set members 484 * \code 485 * void iMesh_rmvEntSet(iMesh_Instance instance, 486 * void iMesh_addEntSet(iMesh_Instance instance, 487 * \endcode 488 * C. deletion of entities from whole iMesh_Instance 489 * \code 490 * void iMesh_deleteEntArr(iMesh_Instance instance, 491 * void iMesh_deleteEnt(iMesh_Instance instance, 492 * \endcode 493 * D. creation of entities (effects root set) 494 * \code 495 * void iMesh_createEntSet(iMesh_Instance instance, 496 * void iMesh_createVtxArr(iMesh_Instance instance, 497 * void iMesh_createEntArr(iMesh_Instance instance, 498 * void iMesh_createVtx(iMesh_Instance instance, 499 * void iMesh_createEnt(iMesh_Instance instance, 500 * \endcode 501 * E. destruction of entity sets 502 * \code 503 * void iMesh_destroyEntSet(iMesh_Instance instance, 504 * \endcode 505 506 * By container modification, we mean that of the above operations occur on 507 * the container between iterator initialization and reset. 508 * 509 * For purposes of this discussion, there is no distinction between any of 510 * these <em>kinds of</em> modifications. What is true for any is true for 511 * all. Below, the words <em>add</em> and <em>remove</em> are used to 512 * represent any of the modifications that add members or remove members 513 * regardless of the <em>kind of operation</em> above. 514 * 515 * Resilient iterators are not effected by modifications involving set members: 516 * 517 * Iterators are currently defined to iterate over *only* the entity members 518 * of a container. In particular, if the container is modified by 519 * adding/removing sets from the container, this will have no impact on 520 * the iterator. This is true for set-type sets and list-type sets. 521 * 522 * Resilient iterator's <em>current position</em> not effected by modification: 523 * 524 * If the container is modified, the iterator will continue to properly 525 * <em>keep track of</em> the member it was currently pointing at. If a 526 * modification occurs that removes the member it was currently pointing at, 527 * the iterator will be advanced to the <em>next</em> (not already deleted) 528 * member it would have proceeded to. In this way, the iterator is guaranteed 529 * to always point at a valid member or to the end of the set, in the case 530 * that the member being removed is the last one. 531 * 532 * A resilient iterator must skip over removed members: 533 * 534 * If the container is modified by removing members, the iterator will guarantee 535 * not to <em>land on</em> (e.g. return) those members as iteration proceeds. 536 * This is true of set-type sets and list-type sets. 537 * 538 * A resilient iterator on set-type sets <em>may</em> fail to return added members: 539 * 540 * If the container is a set-type (<em>duplicate preventing</em>) container and 541 * it is modified by adding members, the iterator <em>may</em> skip over (e.g. 542 * fail to return) members that have been added. In other words, there is no 543 * guarantee in this circumstance that an iterator will return added members. 544 * 545 * A resilient iterator on list-type sets <em>must</em> return added members. 546 * If it is a list-type (<em>order preserving</em>) container, then the iterator 547 * <em>must</em> guarantee to return the added members. 548 * 549 * A non-resilient iterator may or may not behave like a resilient iterator in 550 * some or all of the circumstances described above. There are no guarantees 551 * about how a non-resilient iterator will behave. The behavior of a non-resilient 552 * iterator in the presence of container modifications is left entirely up 553 * to the implementation. 554 * 555 * If upon initializing an iterator, an application requests it be resilient and 556 * the implementation is unable to support that, the iterator initialization 557 * request shall fail and return error iBase_NOT_SUPPORTED. 558 ******************************************************************************/ 559 560 #ifdef __cplusplus 561 } 562 #endif 563 564 #endif /* #ifndef _ITAPS_iBase */ 565