]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/lib/iter.qh
#pragma once
[xonotic/xonotic-data.pk3dir.git] / qcsrc / lib / iter.qh
1 #pragma once
2
3 #define FOREACH_ARRAY(arr, start, end, cond, body) \
4         MACRO_BEGIN \
5         { \
6                 for (int _i = start; _i < end; ++_i) \
7                 { \
8                         const noref int i = _i; \
9                         const noref entity it = arr[i]; \
10                         if (cond) { LAMBDA(body) } \
11                 } \
12         } MACRO_END
13
14 #define FOREACH_LIST(list, next, cond, body) \
15         MACRO_BEGIN \
16         { \
17                 int _i = 0; \
18                 for (entity _it = list##_first; _it; (_it = _it.next, ++_i)) \
19                 { \
20                         const noref int i = _i; \
21                         const noref entity it = _it; \
22                         if (cond) { LAMBDA(body) } \
23                 } \
24         } MACRO_END
25
26 #define FOREACH_WORD(words, cond, body) \
27         MACRO_BEGIN \
28         { \
29                 string _words = words; \
30                 int _i = 0; \
31                 for (string _it; (_it = car(_words)); (_words = cdr(_words), ++_i)) \
32                 { \
33                         const noref int i = _i; \
34                         const noref string it = _it; \
35                         if (cond) { LAMBDA(body) } \
36                 } \
37         } MACRO_END
38
39 #define STRING_ITERATOR(this, s, i) \
40         string this##_s = s; \
41         int this##_i = i
42
43 #define STRING_ITERATOR_SET(this, s, i) \
44         MACRO_BEGIN { \
45                 this##_s = s; \
46                 this##_i = i; \
47         } MACRO_END
48
49 #define STRING_ITERATOR_GET(this) str2chr(this##_s, this##_i++)
50
51 #define FOREACH_CHAR(s, cond, body) \
52         MACRO_BEGIN \
53         { \
54                 STRING_ITERATOR(iter, s, 0); \
55                 int _it; \
56                 while ((_it = STRING_ITERATOR_GET(iter)) > 0) \
57                 { \
58                         const noref int it = _it; \
59                         if (cond) { LAMBDA(body) } \
60                 } \
61         } MACRO_END
62
63 #if defined(CSQC)
64         entity(.string fld, string match, .entity tofield) _findchainstring_tofield = #402;
65         entity(.entity fld, entity match, .entity tofield) findchainentity_tofield = #403;
66         entity(.float fld, float match, .entity tofield) _findchainfloat_tofield = #403;
67         entity(.float fld, float match, .entity tofield) _findchainflags_tofield = #450;
68 #elif defined(SVQC)
69         entity(.string fld, string match, .entity tofield) _findchainstring_tofield = #402;
70         entity(.entity fld, entity match, .entity tofield) findchainentity_tofield = #403;
71         entity(.float fld, float match, .entity tofield) _findchainfloat_tofield = #403;
72         entity(.float fld, float match, .entity tofield) _findchainflags_tofield = #450;
73 #elif defined(MENUQC)
74         entity(.string fld, string match, .entity tofield) _findchainstring_tofield = #26;
75         entity(.entity fld, entity match, .entity tofield) findchainentity_tofield = #27;
76         entity(.float fld, float match, .entity tofield) _findchainfloat_tofield = #27;
77         entity(.float fld, float match, .entity tofield) _findchainflags_tofield = #88;
78 #endif
79
80 .entity _FOREACH_ENTITY_fld;
81 .entity _FOREACH_ENTITY_next;
82
83 #define FOREACH_ENTITY_UNORDERED(cond, body) \
84         MACRO_BEGIN { \
85                 int _i = 0; \
86                 for (entity _it = findchainentity_tofield(_FOREACH_ENTITY_fld, NULL, _FOREACH_ENTITY_next); _it; (_it = _it._FOREACH_ENTITY_next, ++_i)) \
87                 { \
88                         const noref int i = _i; \
89                         const noref entity it = _it; \
90                         if (cond) { LAMBDA(body) } \
91                 } \
92         } MACRO_END
93
94 #define FOREACH_ENTITY_ORDERED(cond, body) \
95         MACRO_BEGIN { \
96                 int _i = 0; \
97                 for (entity _it = NULL; (_it = nextent(_it)); ++_i) \
98                 { \
99                         const noref int i = _i; \
100                         const noref entity it = _it; \
101                         if (cond) { LAMBDA(body) } \
102                 } \
103         } MACRO_END
104
105 #define FOREACH_ENTITY_FLOAT(fld, match, body) \
106         MACRO_BEGIN { \
107                 int _i = 0; \
108                 for (entity _it = _findchainfloat_tofield(fld, match, _FOREACH_ENTITY_next); _it; (_it = _it._FOREACH_ENTITY_next, ++_i)) \
109                 { \
110                         const noref int i = _i; \
111                         const noref entity it = _it; \
112                         LAMBDA(body) \
113                 } \
114         } MACRO_END
115
116 #define FOREACH_ENTITY_FLAGS(fld, match, body) \
117         MACRO_BEGIN { \
118                 int _i = 0; \
119                 for (entity _it = _findchainflags_tofield(fld, match, _FOREACH_ENTITY_next); _it; (_it = _it._FOREACH_ENTITY_next, ++_i)) \
120                 { \
121                         const noref int i = _i; \
122                         const noref entity it = _it; \
123                         LAMBDA(body) \
124                 } \
125         } MACRO_END
126
127 #define FOREACH_ENTITY_CLASS(class, cond, body) \
128         MACRO_BEGIN { \
129                 int _i = 0; \
130                 for (entity _it = _findchainstring_tofield(classname, class, _FOREACH_ENTITY_next); _it; (_it = _it._FOREACH_ENTITY_next, ++_i)) \
131                 { \
132                         const noref int i = _i; \
133                         const noref entity it = _it; \
134                         if (cond) { LAMBDA(body) } \
135                 } \
136         } MACRO_END
137
138 #define FOREACH_ENTITY_ENT(fld, match, body) \
139         do { \
140                 int _i = 0; \
141                 for (entity _it = findchainentity_tofield(fld, match, _FOREACH_ENTITY_next); _it; (_it = _it._FOREACH_ENTITY_next, ++_i)) \
142                 { \
143                         const noref int i = _i; \
144                         const noref entity it = _it; \
145                         LAMBDA(body) \
146                 } \
147         } \
148         while (0)
149
150 #define FOREACH_ENTITY(cond, body) FOREACH_ENTITY_UNORDERED(cond, body)
151
152 #define FOREACH(list, cond, body) FOREACH_LIST(list, enemy, cond, body)