aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/basetypes/MCIterator.h
blob: e9be60e06e85a4f14207cf8487b86d6e593f33c7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
//
//  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 <MailCore/MCArray.h>
#include <MailCore/MCHashMap.h>
#include <MailCore/MCAutoreleasePool.h>
#include <string.h>

#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_foreachdictionaryKey(keyType, __key, __dictionary) \
keyType * __key; \
DictionaryIterator __key##__iterator = DictionaryIteratorInit(__dictionary, true, false); \
while (DictionaryIteratorRun(&__key##__iterator)) \
while (DictionaryIteratorNext(&__key##__iterator, &__key, NULL))

#define mc_foreachdictionaryValue(valueType, __value, __dictionary) \
valueType * __value; \
DictionaryIterator __value##__iterator = DictionaryIteratorInit(__dictionary, false, true); \
while (DictionaryIteratorRun(&__value##__iterator)) \
while (DictionaryIteratorNext(&__value##__iterator, NULL, &__value))

#define mc_foreachdictionaryKeyAndValue(__key, __value, __dictionary) \
keyType * __key; \
valueType * __value; \
DictionaryIterator __key##__value##__iterator = DictionaryIteratorInit(__dictionary, true, true); \
while (DictionaryIteratorRun(&__key##__value##__iterator)) \
while (DictionaryIteratorNext(&__key##__value##__iterator, &__key, &__value))

namespace mailcore {
    
    struct ArrayIterator {
        unsigned index;
        unsigned count;
        Array * array;
    };
    
    static inline ArrayIterator ArrayIteratorInit(Array * array)
    {
        ArrayIterator iterator = { 0, array->count(), 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 FastDictionaryIteratorInit(HashMap * hashmap, bool useKeys, bool useValues)
    {
        AutoreleasePool * pool = new AutoreleasePool();
        Array * keys =  useKeys ? hashmap->allKeys() : NULL;
        Array * values = useValues ? hashmap->allValues() : NULL;
        keys->retain();
        values->retain();
        HashMapIterator iterator = { false, 0, hashmap->count(), 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 DictionaryIteratorRun(HashMapIterator * iterator)
    {
        if (iterator->cleanup) {
            iterator->cleanup = true;
            return true;
        } else {
            iterator->keys->release();
            iterator->values->release();
            return false;
        }
    }

};

#endif