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" } */
9 /* { dg-additional-options "-Wno-objc-root-class" } */
11 #include "../objc-obj-c++-shared/TestsuiteObject.m"
12 #ifndef __NEXT_RUNTIME__
13 #include <objc/NXConstStr.h>
15 #include "../objc-obj-c++-shared/nsconstantstring-class.h"
18 extern int printf (const char *, ...);
22 struct __objcFastEnumerationState
26 unsigned long *mutationsPtr;
27 unsigned long extra[5];
31 /* A mini-array implementation that can be used to test fast
32 enumeration. You create the array with some objects; you can
33 mutate the array, and you can fast-enumerate it.
35 @interface MyArray : TestsuiteObject
39 unsigned long mutated;
41 - (id) initWithLength: (unsigned int)l objects: (id *)o;
43 - (unsigned long)countByEnumeratingWithState: (struct __objcFastEnumerationState *)state
44 objects:(id *)stackbuf
45 count:(unsigned long)len;
48 @implementation MyArray : TestsuiteObject
49 - (id) initWithLength: (unsigned int)l
61 - (unsigned long)countByEnumeratingWithState: (struct __objcFastEnumerationState*)state
62 objects: (id*)stackbuf
63 count: (unsigned long)len
65 unsigned long i, batch_size;
67 /* We keep how many objects we served in the state->state counter. So the next batch
68 will contain up to length - state->state objects. */
69 batch_size = length - state->state;
71 /* Make obvious adjustments. */
78 /* Copy the objects. */
79 for (i = 0; i < batch_size; i++)
80 stackbuf[i] = objects[i];
82 state->state += batch_size;
83 state->itemsPtr = stackbuf;
84 state->mutationsPtr = &mutated;
93 TestsuiteObject *object;
94 int test_variable, counter, i;
97 array = [[MyArray alloc] initWithLength: 0
100 /* Test that an empty array does nothing. */
101 for (object in array)
107 /* Test iterating over 1 object. */
108 objects = malloc (sizeof (id) * 1);
109 objects[0] = @"One Object";
111 array = [[MyArray alloc] initWithLength: 1
114 for (object in array)
115 printf ("%p\n", object);
117 /* Test iterating over 20 objects. */
118 objects = malloc (sizeof (id) * 20);
119 for (i = 0; i < 20; i++)
120 objects[i] = @"object";
122 array = [[MyArray alloc] initWithLength: 20
125 for (object in array)
126 printf ("%p\n", object);
128 /* Test iterating over 200 objects. */
129 objects = malloc (sizeof (id) * 200);
130 for (i = 0; i < 200; i++)
131 objects[i] = @"object";
133 array = [[MyArray alloc] initWithLength: 200
137 for (object in array)
146 printf ("Counter was %d (should be 200)\n", counter);
148 /* Test iterating again over the same array. */
150 for (object in array)
159 printf ("Counter was %d (should be 200)\n", counter);
161 /* Test nested iterations. */
162 objects = malloc (sizeof (id) * 20);
163 for (i = 0; i < 20; i++)
164 objects[i] = @"object";
166 array = [[MyArray alloc] initWithLength: 20
169 for (object in array)
172 for (another_object in array)
173 if (another_object != nil)
177 printf ("Counter was %d (should be 400)\n", counter);
182 /* Test 'continue'. */
183 objects = malloc (sizeof (id) * 20);
184 for (i = 0; i < 20; i++)
185 objects[i] = @"object";
187 array = [[MyArray alloc] initWithLength: 20
190 for (object in array)
198 printf ("Counter was %d (should be 15)\n", counter);
204 objects = malloc (sizeof (id) * 20);
205 for (i = 0; i < 20; i++)
206 objects[i] = @"object";
208 array = [[MyArray alloc] initWithLength: 20
211 for (object in array)
219 printf ("Counter was %d (should be 15)\n", counter);
224 /* Test 'break' and 'continue' in nested iterations. */
225 objects = malloc (sizeof (id) * 20);
226 for (i = 0; i < 20; i++)
227 objects[i] = @"object";
229 array = [[MyArray alloc] initWithLength: 20
232 for (object in array)
234 int local_counter = 0;
237 /* Each internal loop should increase counter by 24. */
238 for (another_object in array)
242 if (local_counter == 10)
244 counter = counter + 20;
248 if (local_counter >= 5)
254 /* Exit after 4 iterations. */
259 printf ("Counter was %d (should be 96)\n", counter);
264 /* Test that if we 'break', the object is set to the last one, while
265 if we run out of objects, it is set to 'nil'. */
266 for (object in array)
272 for (object in array)
278 /* Test that C for loops still work. */
281 for (counter = 0; counter < 4; counter++)
284 if (test_variable != 4)