2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 #ifndef _OS_OSORDEREDSET_H
30 #define _OS_OSORDEREDSET_H
32 #include <libkern/c++/OSCollection.h>
33 #include <libkern/OSTypes.h>
41 * This header declares the OSOrderedSet collection class.
49 * OSOrderedSet provides an ordered set store of objects.
52 * OSOrderedSet is a container for Libkern C++ objects
54 * @link //apple_ref/doc/class/OSMetaClassBase OSMetaClassBase@/link,
55 * in particular @link //apple_ref/doc/class/OSObject OSObject@/link).
56 * Storage and access follow ordered set logic.
57 * A given object is stored in the set only once, but you can:
59 * <li>Define a sorting function for automated ordering
60 * (upon addition only)</li>
61 * <li>Manually insert new objects in the set (overriding sorting)</li>
62 * <li>Add and remove objects in the set</li>
63 * <li>Test whether the set contains a particular object</li>
64 * <li>Get the object stored at a particular index.</li>
67 * Note that automated ordering is performed only upon addition of objects
68 * and depends on the existing objects being properly sorted.
69 * There is no function to re-sort the contents of an OSOrderedSet
70 * or to change the ordering function.
71 * In general, you should either use the one ordered-insertion function,
72 * or the indexed-insertion functions, and not mix the two.
74 * As with all Libkern collection classes,
75 * OSOrderedSet retains objects added to it,
76 * and releases objects removed from it.
77 * An OSOrderedSet also grows as necessary to accommodate new objects,
78 * <i>unlike</i> Core Foundation collections (it does not, however, shrink).
80 * <b>Use Restrictions</b>
82 * With very few exceptions in the I/O Kit, all Libkern-based C++
83 * classes, functions, and macros are <b>unsafe</b>
84 * to use in a primary interrupt context.
85 * Consult the I/O Kit documentation related to primary interrupts
86 * for more information.
88 * OSOrderedSet provides no concurrency protection;
89 * it's up to the usage context to provide any protection necessary.
90 * Some portions of the I/O Kit, such as
91 * @link //apple_ref/doc/class/IORegistryEntry IORegistryEntry@/link,
92 * handle synchronization via defined member functions for setting
95 class OSOrderedSet
: public OSCollection
97 OSDeclareDefaultStructors(OSOrderedSet
)
101 * @typedef OSOrderFunction
104 * The sorting function used by an OSOrderedSet to order objects.
106 * @param obj1 An object from the ordered set. May be <code>NULL</code>.
107 * @param obj2 The object being ordered within the ordered set.
108 * May be <code>NULL</code>.
109 * @param context A pointer to a user-provided context. May be <code>NULL</code>.
112 * A comparison result of the object:
114 * <li>a negative value if obj2 should precede obj1,</li>
115 * <li>a positive value if obj1 should precede obj2,</li>
116 * <li>and 0 if obj1 and obj2 have an equivalent ordering.</li>
119 typedef SInt32 (*OSOrderFunction
)(const OSMetaClassBase
* obj1
,
120 const OSMetaClassBase
* obj2
,
124 struct _Element
* array
;
125 OSOrderFunction ordering
;
128 unsigned int capacity
;
129 unsigned int capacityIncrement
;
131 struct ExpansionData
{ };
133 /* Reserved for future use. (Internal use only) */
134 ExpansionData
*reserved
;
137 /* OSCollectionIterator interfaces. */
138 virtual unsigned int iteratorSize() const APPLE_KEXT_OVERRIDE
;
139 virtual bool initIterator(void *iterator
) const APPLE_KEXT_OVERRIDE
;
140 virtual bool getNextObjectForIterator(void *iterator
, OSObject
**ret
) const APPLE_KEXT_OVERRIDE
;
145 * @function withCapacity
148 * Creates and initializes an empty OSOrderedSet.
150 * @param capacity The initial storage capacity
151 * of the new ordered set object.
152 * @param orderFunc A C function that implements the sorting algorithm
154 * @param orderingContext An ordering context,
155 * which is passed to <code>orderFunc</code>.
157 * An empty instance of OSOrderedSet
158 * with a retain count of 1;
159 * <code>NULL</code> on failure.
162 * <code>capacity</code> must be nonzero.
163 * The new OSOrderedSet will grow as needed
164 * to accommodate more key/object pairs
165 * (<i>unlike</i> Core Foundation collections,
166 * for which the initial capacity is a hard limit).
168 * If <code>orderFunc</code> is provided, it is used by
170 * //apple_ref/cpp/instm/OSOrderedSet/setObject/virtualbool/(constOSMetaClassBase*)
171 * setObject(const OSMetaClassBase *)@/link</code>
172 * to determine where to insert a new object.
173 * Other object-setting functions ignore ordering.
175 * <code>orderingContext</code> is not retained or otherwise memory-managed
176 * by the ordered set.
177 * If it needs to be deallocated,
178 * you must track references to it and the ordered set
179 * in order to deallocate it appropriately.
181 * <code>@link getOrderingRef getOrderingRef@/link</code>.
183 static OSOrderedSet
* withCapacity(
184 unsigned int capacity
,
185 OSOrderFunction orderFunc
= 0,
186 void * orderingContext
= 0);
190 * @function initWithCapacity
193 * Initializes a new instance of OSOrderedSet.
195 * @param capacity The initial storage capacity
196 * of the new ordered set object.
197 * @param orderFunc A C function that implements the sorting algorithm
199 * @param orderingContext An ordering context,
200 * which is passed to <code>orderFunc</code>.
203 * <code>true</code> on success, <code>false</code> on failure.
206 * Not for general use. Use the static instance creation method
208 * //apple_ref/cpp/clm/OSOrderedSet/withCapacity/staticOSOrderedSet*\/(unsignedint,OSOrderFunction,void*)
209 * withCapacity@/link</code>
212 * <code>capacity</code> must be nonzero.
213 * The new set will grow as needed to accommodate more key/object pairs
214 * (<i>unlike</i> Core Foundation collections,
215 * for which the initial capacity is a hard limit).
217 * If <code>orderFunc</code> is provided, it is used by
219 * //apple_ref/cpp/instm/OSOrderedSet/setObject/virtualbool/(constOSMetaClassBase*)
220 * setObject(const OSMetaClassBase *)@/link</code>
221 * to determine where to insert a new object.
222 * Other object-setting functions ignore ordering.
224 * <code>orderingContext</code> is not retained or otherwise memory-managed
225 * by the ordered set.
226 * If it needs to be deallocated,
227 * you must track references to it and the ordered set
228 * in order to deallocate it appropriately.
230 * <code>@link getOrderingRef getOrderingRef@/link</code>.
232 virtual bool initWithCapacity(
233 unsigned int capacity
,
234 OSOrderFunction orderFunc
= 0,
235 void * orderingContext
= 0);
242 * Deallocatesand releases any resources
243 * used by the OSOrderedSet instance.
246 * This function should not be called directly;
249 * //apple_ref/cpp/instm/OSObject/release/virtualvoid/()
250 * release@/link</code>
253 virtual void free() APPLE_KEXT_OVERRIDE
;
260 * Returns the current number of objects within the ordered set.
263 * The current number of objects within the ordered set.
265 virtual unsigned int getCount() const APPLE_KEXT_OVERRIDE
;
269 * @function getCapacity
272 * Returns the number of objects the ordered set
273 * can store without reallocating.
276 * The number objects the ordered set
277 * can store without reallocating.
280 * OSOrderedSet objects grow when full to accommodate additional objects.
283 * //apple_ref/cpp/instm/OSOrderedSet/getCapacityIncrement/virtualunsignedint/()
284 * getCapacityIncrement@/link</code>
287 * //apple_ref/cpp/instm/OSOrderedSet/ensureCapacity/virtualunsignedint/(unsignedint)
288 * ensureCapacity@/link</code>.
290 virtual unsigned int getCapacity() const APPLE_KEXT_OVERRIDE
;
294 * @function getCapacityIncrement
297 * Returns the storage increment of the ordered set.
300 * The storage increment of the ordered set.
303 * An OSOrderedSet allocates storage for objects in multiples
304 * of the capacity increment.
306 virtual unsigned int getCapacityIncrement() const APPLE_KEXT_OVERRIDE
;
310 * @function setCapacityIncrement
313 * Sets the storage increment of the ordered set.
316 * The new storage increment of the ordered set,
317 * which may be different from the number requested.
320 * An OSOrderedSet allocates storage for objects in multiples
321 * of the capacity increment.
322 * Calling this function does not immediately reallocate storage.
324 virtual unsigned int setCapacityIncrement(unsigned increment
) APPLE_KEXT_OVERRIDE
;
328 * @function ensureCapacity
331 * Ensures the set has enough space
332 * to store the requested number of distinct objects.
334 * @param newCapacity The total number of distinct objects the ordered set
335 * should be able to store.
338 * The new capacity of the ordered set,
339 * which may be different from the number requested
340 * (if smaller, reallocation of storage failed).
343 * This function immediately resizes the ordered set, if necessary,
344 * to accommodate at least <code>newCapacity</code> distinct objects.
345 * If <code>newCapacity</code> is not greater than the current capacity,
346 * or if an allocation error occurs, the original capacity is returned.
348 * There is no way to reduce the capacity of an OSOrderedSet.
350 virtual unsigned int ensureCapacity(unsigned int newCapacity
) APPLE_KEXT_OVERRIDE
;
354 * @function flushCollection
357 * Removes and releases all objects within the ordered set.
360 * The ordered set's capacity (and therefore direct memory consumption)
361 * is not reduced by this function.
363 virtual void flushCollection() APPLE_KEXT_OVERRIDE
;
367 * @function setObject
370 * Adds an object to the OSOrderedSet if it is not already present,
371 * storing it in sorted order if there is an order function.
373 * @param anObject The OSMetaClassBase-derived object to be added
374 * to the ordered set.
376 * <code>true</code> if <code>anObject</code> was successfully
377 * added to the ordered set, <code>false</code> otherwise
378 * (including if it was already in the ordered set).
381 * The set adds storage to accomodate the new object, if necessary.
382 * If successfully added, the object is retained.
384 * If <code>anObject</code> is not already in the ordered set
385 * and there is an order function,
386 * this function loops through the existing objects,
387 * calling the @link OSOrderFunction order function@/link
388 * with arguments each existingObject, <code>anObject</code>,
389 * and the ordering context
390 * (or <code>NULL</code> if none was set),
391 * until the order function returns
392 * a value <i>greater than</i> or equal to 0.
393 * It then inserts <code>anObject</code> at the index of the existing object.
395 * If there is no order function, the object is inserted at index 0.
397 * A <code>false</code> return value can mean either
398 * that <code>anObject</code> is already present in the set,
399 * or that a memory allocation failure occurred.
400 * If you need to know whether the object
401 * is already present, use
403 * //apple_ref/cpp/instm/OSOrderedSet/containsObject/virtualbool/(constOSMetaClassBase*)
404 * containsObject(const OSMetaClassBase *)@/link</code>.
406 virtual bool setObject(const OSMetaClassBase
* anObject
);
410 * @function setFirstObject
413 * Adds an object to the OSOrderedSet at index 0
414 * if it is not already present.
416 * @param anObject The OSMetaClassBase-derived object
417 * to be added to the ordered set.
419 * <code>true</code> if <code>anObject</code> was successfully added
420 * to the ordered set, <code>false</code> otherwise
421 * (including if it was already in the ordered set at any index).
424 * The set adds storage to accomodate the new object, if necessary.
425 * If successfully added, the object is retained.
427 * This function ignores any ordering function of the ordered set,
428 * and can disrupt the automatic sorting mechanism.
429 * Only call this function if you are managing the ordered set directly.
431 * A <code>false</code> return value can mean either that <code>anObject</code>
432 * is already present in the set,
433 * or that a memory allocation failure occurred.
434 * If you need to know whether the object
435 * is already present, use
437 * //apple_ref/cpp/instm/OSOrderedSet/containsObject/virtualbool/(constOSMetaClassBase*)
438 * containsObject(const OSMetaClassBase *)@/link</code>.
440 virtual bool setFirstObject(const OSMetaClassBase
* anObject
);
444 * @function setLastObject
447 * Adds an object at the end of the OSOrderedSet
448 * if it is not already present.
450 * @param anObject The OSMetaClassBase-derived object to be added
451 * to the ordered set.
453 * <code>true</code> if <code>anObject</code> was successfully added
454 * to the ordered set, <code>false</code> otherwise
455 * (including if it was already in the ordered set at any index).
458 * The set adds storage to accomodate the new object, if necessary.
459 * If successfully added, the object is retained.
461 * This function ignores any ordering function of the ordered set,
462 * and can disrupt the automatic sorting mechanism.
463 * Only call this function if you are managing the ordered set directly.
465 * A <code>false</code> return value can mean either that <code>anObject</code>
466 * is already present in the set,
467 * or that a memory allocation failure occurred.
468 * If you need to know whether the object
469 * is already present, use
471 * //apple_ref/cpp/instm/OSOrderedSet/containsObject/virtualbool/(constOSMetaClassBase*)
472 * containsObject(const OSMetaClassBase *)@/link</code>.
474 virtual bool setLastObject(const OSMetaClassBase
* anObject
);
478 * @function removeObject
481 * Removes an object from the ordered set.
483 * @param anObject The OSMetaClassBase-derived object
484 * to be removed from the ordered set.
487 * The object removed from the ordered set is released.
489 virtual void removeObject(const OSMetaClassBase
* anObject
);
493 * @function containsObject
496 * Checks the ordered set for the presence of an object.
498 * @param anObject The OSMetaClassBase-derived object to check for
499 * in the ordered set.
502 * <code>true</code> if <code>anObject</code> is present
503 * within the ordered set, <code>false</code> otherwise.
506 * Pointer equality is used.
507 * This function returns <code>false</code> if passed <code>NULL</code>.
509 virtual bool containsObject(const OSMetaClassBase
* anObject
) const;
516 * Checks the ordered set for the presence of an object.
518 * @param anObject The OSMetaClassBase-derived object to check for
519 * in the ordered set.
522 * <code>true</code> if <code>anObject</code> is present
523 * within the ordered set, <code>false</code> otherwise.
526 * Pointer equality is used.
527 * Returns <code>false</code> if passed <code>NULL</code>.
530 * //apple_ref/cpp/instm/OSOrderedSet/containsObject/virtualbool/(constOSMetaClassBase*)
531 * containsObject(const OSMetaClassBase *)@/link</code>
532 * checks for <code>NULL</code> before scanning the contents,
533 * and is therefore more efficient than this function.
535 virtual bool member(const OSMetaClassBase
* anObject
) const;
539 * @function getFirstObject
542 * Returns the object at index 0 in the ordered set if there is one.
545 * The object at index 0 in the ordered set if there is one,
546 * otherwise <code>NULL</code>.
549 * The returned object will be released if removed from the ordered set;
550 * if you plan to store the reference, you should call
552 * //apple_ref/cpp/instm/OSObject/retain/virtualvoid/()
553 * retain@/link</code>
556 virtual OSObject
* getFirstObject() const;
560 * @function getLastObject
563 * Returns the last object in the ordered set if there is one.
566 * The last object in the ordered set if there is one,
567 * otherwise <code>NULL</code>.
570 * The returned object will be released if removed from the ordered set;
571 * if you plan to store the reference, you should call
573 * //apple_ref/cpp/instm/OSObject/retain/virtualvoid/()
574 * retain@/link</code>
577 virtual OSObject
* getLastObject() const;
581 * @function orderObject
584 * Calls the ordered set's order function against a <code>NULL</code> object.
586 * @param anObject The object to be ordered.
589 * The ordering value for the object.
592 * This function calls the ordered set's
593 * @link OSOrderFunction order function@/link
594 * with <code>anObject</code>, <code>NULL</code>, and the ordering context
595 * (or <code>NULL</code> if none was set),
596 * and returns the result of that function.
598 virtual SInt32
orderObject(const OSMetaClassBase
* anObject
);
602 * @function setObject
605 * Adds an object to an OSOrderedSet at a specified index
606 * if it is not already present.
608 * @param index The index at which to insert the new object.
609 * @param anObject The OSMetaClassBase-derived object to be added
610 * to the ordered set.
613 * <code>true</code> if the object was successfully added
614 * to the ordered set, <code>false</code> otherwise
615 * (including if it was already in the set).
618 * The set adds storage to accomodate the new object, if necessary.
619 * If successfully added, the object is retained.
621 * This function ignores any ordering function of the ordered set,
622 * and can disrupt the automatic sorting mechanism.
623 * Only call this function if you are managing the ordered set directly.
625 * A <code>false</code> return value can mean either that the object
626 * is already present in the set,
627 * or that a memory allocation failure occurred.
628 * If you need to know whether the object
629 * is already present, use
630 * <code>@link //apple_ref/cpp/instm/OSOrderedSet/containsObject/virtualbool/(constOSMetaClassBase*)
631 * containsObject containsObject@/link</code>.
633 virtual bool setObject(
635 const OSMetaClassBase
* anObject
);
639 * @function getObject
642 * Gets the object at a particular index.
644 * @param index The index into the set.
646 * The object at the given index,
647 * or <code>NULL</code> if none exists at that location.
650 * The returned object will be released if removed from the set;
651 * if you plan to store the reference, you should call
653 * //apple_ref/cpp/instm/OSObject/retain/virtualvoid/()
654 * retain@/link</code>
657 virtual OSObject
* getObject(unsigned int index
) const;
661 * @function getOrderingRef
664 * Returns the ordering context the ordered set was created with.
667 * The ordered set's ordering context,
668 * or <code>NULL</code> if it doesn't have one.
670 virtual void * getOrderingRef();
674 * @function isEqualTo
677 * Tests the equality of two OSOrderedSet objects.
679 * @param anOrderedSet The ordered set object being compared
680 * against the receiver.
682 * <code>true</code> if the two sets are equivalent,
683 * <code>false</code> otherwise.
686 * Two OSOrderedSet objects are considered equal if they have same count
687 * and the same object pointer values in the same order.
689 virtual bool isEqualTo(const OSOrderedSet
* anOrderedSet
) const;
693 * @function isEqualTo
696 * Tests the equality of an OSOrderedSet
697 * against an arbitrary object.
699 * @param anObject The object being compared against the receiver.
701 * <code>true</code> if the two objects are equivalent,
702 * <code>false</code> otherwise.
705 * An OSOrderedSet object is considered equal to another object
706 * if the other object is derived from OSOrderedSet
707 * and compares equal as an OSOrderedSet.
709 virtual bool isEqualTo(const OSMetaClassBase
* anObject
) const APPLE_KEXT_OVERRIDE
;
713 * @function setOptions
715 * Recursively sets option bits in the ordered set
716 * and all child collections.
718 * @param options A bitfield whose values turn the options on (1) or off (0).
719 * @param mask A mask indicating which bits
720 * in <code>options</code> to change.
721 * Pass 0 to get the whole current options bitfield
722 * without changing any settings.
723 * @param context Unused.
726 * The options bitfield as it was before the set operation.
729 * Kernel extensions should not call this function.
731 * Child collections' options are changed only if the receiving ordered set's
732 * options actually change.
734 virtual unsigned setOptions(
737 void * context
= 0) APPLE_KEXT_OVERRIDE
;
741 * @function copyCollection
744 * Creates a deep copy of this ordered set and its child collections.
746 * @param cycleDict A dictionary of all of the collections
747 * that have been copied so far,
748 * which is used to track circular references.
749 * To start the copy at the top level,
750 * pass <code>NULL</code>.
753 * The newly copied ordered set, with a retain count of 1,
754 * or <code>NULL</code> if there is insufficient memory to do the copy.
757 * The receiving ordered set, and any collections it contains,
758 * recursively, are copied.
759 * Objects that are not derived from OSCollection are retained
760 * rather than copied.
762 OSCollection
*copyCollection(OSDictionary
* cycleDict
= 0) APPLE_KEXT_OVERRIDE
;
764 OSMetaClassDeclareReservedUnused(OSOrderedSet
, 0);
765 OSMetaClassDeclareReservedUnused(OSOrderedSet
, 1);
766 OSMetaClassDeclareReservedUnused(OSOrderedSet
, 2);
767 OSMetaClassDeclareReservedUnused(OSOrderedSet
, 3);
768 OSMetaClassDeclareReservedUnused(OSOrderedSet
, 4);
769 OSMetaClassDeclareReservedUnused(OSOrderedSet
, 5);
770 OSMetaClassDeclareReservedUnused(OSOrderedSet
, 6);
771 OSMetaClassDeclareReservedUnused(OSOrderedSet
, 7);
774 #endif /* ! _OS_OSORDEREDSET_H */