1 /* Test basic Objective-C foreach syntax. This tests iterations, with
2 the basic syntax 'for (object in array) statements'
5 /* { dg-skip-if "No NeXT fast enum. pre-Darwin9" { *-*-darwin[5-8]* } { "-fnext-runtime" } { "" } } */
6 /* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
7 /* { dg-options "-mno-constant-cfstrings" { target *-*-darwin* } } */
8 /* { dg-additional-sources "../objc-obj-c++-shared/nsconstantstring-class-impl.m" } */
10 #include "../objc-obj-c++-shared/TestsuiteObject.m"
11 #ifndef __NEXT_RUNTIME__
12 #include <objc/NXConstStr.h>
14 #include "../objc-obj-c++-shared/nsconstantstring-class.h"
17 extern int printf (const char *, ...);
21 struct __objcFastEnumerationState
25 unsigned long *mutationsPtr;
26 unsigned long extra[5];
30 /* A mini-array implementation that can be used to test fast
31 enumeration. You create the array with some objects; you can
32 mutate the array, and you can fast-enumerate it.
34 @interface MyArray : TestsuiteObject
38 unsigned long mutated;
40 - (id) initWithLength: (unsigned int)l objects: (id *)o;
42 - (unsigned long)countByEnumeratingWithState: (struct __objcFastEnumerationState *)state
43 objects:(id *)stackbuf
44 count:(unsigned long)len;
47 @implementation MyArray : TestsuiteObject
48 - (id) initWithLength: (unsigned int)l
60 - (unsigned long)countByEnumeratingWithState: (struct __objcFastEnumerationState*)state
61 objects: (id*)stackbuf
62 count: (unsigned long)len
64 unsigned long i, batch_size;
66 /* We keep how many objects we served in the state->state counter. So the next batch
67 will contain up to length - state->state objects. */
68 batch_size = length - state->state;
70 /* Make obvious adjustments. */
77 /* Copy the objects. */
78 for (i = 0; i < batch_size; i++)
79 stackbuf[i] = objects[i];
81 state->state += batch_size;
82 state->itemsPtr = stackbuf;
83 state->mutationsPtr = &mutated;
92 TestsuiteObject *object;
93 int test_variable, counter, i;
96 array = [[MyArray alloc] initWithLength: 0
99 /* Test that an empty array does nothing. */
100 for (object in array)
106 /* Test iterating over 1 object. */
107 objects = malloc (sizeof (id) * 1);
108 objects[0] = @"One Object";
110 array = [[MyArray alloc] initWithLength: 1
113 for (object in array)
114 printf ("%p\n", object);
116 /* Test iterating over 20 objects. */
117 objects = malloc (sizeof (id) * 20);
118 for (i = 0; i < 20; i++)
119 objects[i] = @"object";
121 array = [[MyArray alloc] initWithLength: 20
124 for (object in array)
125 printf ("%p\n", object);
127 /* Test iterating over 200 objects. */
128 objects = malloc (sizeof (id) * 200);
129 for (i = 0; i < 200; i++)
130 objects[i] = @"object";
132 array = [[MyArray alloc] initWithLength: 200
136 for (object in array)
145 printf ("Counter was %d (should be 200)\n", counter);
147 /* Test iterating again over the same array. */
149 for (object in array)
158 printf ("Counter was %d (should be 200)\n", counter);
160 /* Test nested iterations. */
161 objects = malloc (sizeof (id) * 20);
162 for (i = 0; i < 20; i++)
163 objects[i] = @"object";
165 array = [[MyArray alloc] initWithLength: 20
168 for (object in array)
171 for (another_object in array)
172 if (another_object != nil)
176 printf ("Counter was %d (should be 400)\n", counter);
181 /* Test 'continue'. */
182 objects = malloc (sizeof (id) * 20);
183 for (i = 0; i < 20; i++)
184 objects[i] = @"object";
186 array = [[MyArray alloc] initWithLength: 20
189 for (object in array)
197 printf ("Counter was %d (should be 15)\n", counter);
203 objects = malloc (sizeof (id) * 20);
204 for (i = 0; i < 20; i++)
205 objects[i] = @"object";
207 array = [[MyArray alloc] initWithLength: 20
210 for (object in array)
218 printf ("Counter was %d (should be 15)\n", counter);
223 /* Test 'break' and 'continue' in nested iterations. */
224 objects = malloc (sizeof (id) * 20);
225 for (i = 0; i < 20; i++)
226 objects[i] = @"object";
228 array = [[MyArray alloc] initWithLength: 20
231 for (object in array)
233 int local_counter = 0;
236 /* Each internal loop should increase counter by 24. */
237 for (another_object in array)
241 if (local_counter == 10)
243 counter = counter + 20;
247 if (local_counter >= 5)
253 /* Exit after 4 iterations. */
258 printf ("Counter was %d (should be 96)\n", counter);
263 /* Test that if we 'break', the object is set to the last one, while
264 if we run out of objects, it is set to 'nil'. */
265 for (object in array)
271 for (object in array)
277 /* Test that C for loops still work. */
280 for (counter = 0; counter < 4; counter++)
283 if (test_variable != 4)