// // MCIterator.h // mailcore2 // // Created by DINH Viêt Hoà on 4/18/13. // Copyright (c) 2013 MailCore. All rights reserved. // #ifndef __MAILCORE_ITERATOR_H_ #define __MAILCORE_ITERATOR_H_ #include #include #include #include #ifdef __cplusplus #define mc_foreacharray(type, __variable, __array) \ type * __variable; \ mailcore::ArrayIterator __variable##__iterator = mailcore::ArrayIteratorInit(__array); \ for (; NULL != (__variable = (type *) mailcore::ArrayIteratorNext(&__variable##__iterator)); ) #define mc_foreacharrayIndex(__index, type, __variable, __array) \ type * __variable; \ mailcore::ArrayIterator __variable##__iterator = mailcore::ArrayIteratorInit(__array); \ for (unsigned int __index = 0; NULL != (__variable = mailcore::ArrayIteratorNext(&__variable##__iterator)); __index++) #define mc_foreachhashmapKey(keyType, __key, __hashmap) \ keyType * __key; \ HashMapIterator __key##__iterator = HashMapIteratorInit(__hashmap, true, false); \ while (HashMapIteratorRun(&__key##__iterator)) \ while (HashMapIteratorNext(&__key##__iterator, &__key, NULL)) #define mc_foreachhashmapValue(valueType, __value, __hashmap) \ valueType * __value; \ HashMapIterator __value##__iterator = HashMapIteratorInit(__hashmap, false, true); \ while (HashMapIteratorRun(&__value##__iterator)) \ while (HashMapIteratorNext(&__value##__iterator, NULL, (Object **) &__value)) #define mc_foreachhashmapKeyAndValue(keyType, __key, valueType, __value, __hashmap) \ keyType * __key; \ valueType * __value; \ HashMapIterator __key##__value##__iterator = HashMapIteratorInit(__hashmap, true, true); \ while (HashMapIteratorRun(&__key##__value##__iterator)) \ while (HashMapIteratorNext(&__key##__value##__iterator, (Object **) &__key, (Object **) &__value)) namespace mailcore { struct ArrayIterator { unsigned index; unsigned count; Array * array; }; static inline ArrayIterator ArrayIteratorInit(Array * array) { ArrayIterator iterator = { 0, array != NULL ? array->count() : 0, array }; return iterator; } static inline Object * ArrayIteratorNext(ArrayIterator * iterator) { if (iterator->index >= iterator->count) { return NULL; } Object * result = iterator->array->objectAtIndex(iterator->index); ++ iterator->index; return result; } struct HashMapIterator { bool cleanup; unsigned index; unsigned count; Array * keys; Array * values; }; static inline HashMapIterator HashMapIteratorInit(HashMap * hashmap, bool useKeys, bool useValues) { AutoreleasePool * pool = new AutoreleasePool(); Array * keys = useKeys ? (hashmap != NULL ? hashmap->allKeys() : NULL) : NULL; Array * values = useValues ? (hashmap != NULL ? hashmap->allValues() : NULL) : NULL; if (keys != NULL) { keys->retain(); } if (values != NULL) { values->retain(); } HashMapIterator iterator = { false, 0, hashmap != NULL ? hashmap->count() : 0, keys, values }; pool->release(); return iterator; } static inline bool HashMapIteratorNext(HashMapIterator * iterator, Object ** keyp, Object ** valuep) { if (iterator->index >= iterator->count) { return false; } if (keyp != NULL) { * keyp = iterator->keys->objectAtIndex(iterator->index); } if (valuep != NULL) { * valuep = iterator->values->objectAtIndex(iterator->index); } iterator->index ++; return true; } static inline bool HashMapIteratorRun(HashMapIterator * iterator) { if (!iterator->cleanup) { iterator->cleanup = true; return true; } else { MC_SAFE_RELEASE(iterator->keys); MC_SAFE_RELEASE(iterator->values); return false; } } }; #endif #endif