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