OSDN Git Service

b6cfe2c0c659342e98becf5c21a407c3ba595c9e
[pf3gnuchains/gcc-fork.git] / gcc / testsuite / objc.dg / foreach-4.m
1 /* Test basic Objective-C foreach syntax.  This tests iterations, with
2    the declaration syntax 'for (id object in array) statements'
3 */
4 /* { dg-do run } */
5 /* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */
6 /* { dg-additional-sources "../objc-obj-c++-shared/Object1.m" } */
7
8 #import "../objc-obj-c++-shared/Object1.h"
9 #import "../objc-obj-c++-shared/next-mapping.h"
10 #ifndef __NEXT_RUNTIME__
11 #include <objc/NXConstStr.h>
12 #endif
13
14 extern int printf (const char *, ...);
15 #include <stdlib.h>
16
17 /*
18 struct __objcFastEnumerationState
19 {
20   unsigned long state;
21   id            *itemsPtr;
22   unsigned long *mutationsPtr;
23   unsigned long extra[5];
24 };
25 */
26
27  /* A mini-array implementation that can be used to test fast
28     enumeration.  You create the array with some objects; you can
29     mutate the array, and you can fast-enumerate it.
30  */
31 @interface MyArray : Object
32 {
33   unsigned int length;
34   id *objects;
35   unsigned long mutated;
36 }
37 - (id) initWithLength: (unsigned int)l  objects: (id *)o;
38 - (void) mutate;
39 - (unsigned long)countByEnumeratingWithState: (struct __objcFastEnumerationState *)state
40                                      objects:(id *)stackbuf 
41                                        count:(unsigned long)len;
42 @end
43
44 @implementation MyArray : Object
45 - (id) initWithLength: (unsigned int)l
46               objects: (id *)o
47 {
48   length = l;
49   objects = o;
50   mutated = 0;
51 }
52 - (void) mutate
53 {
54   mutated = 1;
55 }
56 - (unsigned long)countByEnumeratingWithState: (struct __objcFastEnumerationState*)state 
57                                      objects: (id*)stackbuf
58                                        count: (unsigned long)len
59 {
60   unsigned long i, batch_size;
61
62   /* We keep how many objects we served in the state->state counter.  So the next batch
63      will contain up to length - state->state objects.  */
64   batch_size = length - state->state;
65
66   /* Make obvious adjustments.  */
67   if (batch_size < 0)
68     batch_size = 0;
69
70   if (batch_size > len)
71     batch_size = len;
72
73   /* Copy the objects.  */
74   for (i = 0; i < batch_size; i++)
75     stackbuf[i] = objects[i];
76
77   state->state += batch_size;
78   state->itemsPtr = stackbuf;
79   state->mutationsPtr = &mutated;
80
81   return batch_size;
82 }
83 @end
84
85 int main (void)
86 {
87   MyArray *array;
88   int test_variable, counter, i;
89   id *objects;
90
91   array = [[MyArray alloc] initWithLength: 0
92                            objects: NULL];
93
94   /* Test that an empty array does nothing.  */
95   for (id object in array)
96     abort ();
97
98   /* Test iterating over 1 object.  */
99   objects = malloc (sizeof (id) * 1);
100   objects[0] = @"One Object";
101
102   array = [[MyArray alloc] initWithLength: 1
103                            objects: objects];
104   
105   for (id object in array)
106     printf ("%p\n", object);
107   
108   /* Test iterating over 20 objects.  */
109   objects = malloc (sizeof (id) * 20);
110   for (i = 0; i < 20; i++)
111     objects[i] = @"object";
112   
113   array = [[MyArray alloc] initWithLength: 20
114                            objects: objects];
115   
116   for (id object in array)
117     printf ("%p\n", object);
118
119   /* Test iterating over 200 objects.  */
120   objects = malloc (sizeof (id) * 200);
121   for (i = 0; i < 200; i++)
122     objects[i] = @"object";
123   
124   array = [[MyArray alloc] initWithLength: 200
125                            objects: objects];
126   
127   counter = 0;
128   for (id object in array)
129     {
130       if (object != nil)
131         counter++;
132     }
133
134   if (counter != 200)
135     abort ();
136
137   printf ("Counter was %d (should be 200)\n", counter);
138
139   /* Test iterating again over the same array.  */
140   counter = 0;
141   for (id object in array)
142     {
143       if (object != nil)
144         counter++;
145     }
146
147   if (counter != 200)
148     abort ();
149
150   printf ("Counter was %d (should be 200)\n", counter);
151
152   /* Test nested iterations.  */
153   objects = malloc (sizeof (id) * 20);
154   for (i = 0; i < 20; i++)
155     objects[i] = @"object";
156   
157   array = [[MyArray alloc] initWithLength: 20
158                            objects: objects];
159   counter = 0;
160   for (id object in array)
161     {
162       for (id another_object in array)
163         if (another_object != nil)
164           counter++;
165     }
166
167   printf ("Counter was %d (should be 400)\n", counter);
168
169   if (counter != 400)
170     abort ();
171
172   /* Test 'continue'.  */
173   objects = malloc (sizeof (id) * 20);
174   for (i = 0; i < 20; i++)
175     objects[i] = @"object";
176   
177   array = [[MyArray alloc] initWithLength: 20
178                            objects: objects];
179   counter = 0;
180   for (id object in array)
181     {
182       if (counter == 15)
183         continue;
184
185       counter++;
186     }
187
188   printf ("Counter was %d (should be 15)\n", counter);
189
190   if (counter != 15)
191     abort ();
192
193   /* Test 'break'.  */
194   objects = malloc (sizeof (id) * 20);
195   for (i = 0; i < 20; i++)
196     objects[i] = @"object";
197   
198   array = [[MyArray alloc] initWithLength: 20
199                            objects: objects];
200   counter = 0;
201   for (id object in array)
202     {
203       counter++;
204
205       if (counter == 15)
206         break;
207     }
208
209   printf ("Counter was %d (should be 15)\n", counter);
210
211   if (counter != 15)
212     abort ();
213
214   /* Test 'break' and 'continue' in nested iterations.  */
215   objects = malloc (sizeof (id) * 20);
216   for (i = 0; i < 20; i++)
217     objects[i] = @"object";
218   
219   array = [[MyArray alloc] initWithLength: 20
220                            objects: objects];
221   counter = 0;
222   for (id object in array)
223     {
224       int local_counter = 0;
225
226       /* Each internal loop should increase counter by 24.  */
227       for (id another_object in array)
228         {
229           local_counter++;
230           
231           if (local_counter == 10)
232             {
233               counter = counter + 20;
234               break;
235             }
236
237           if (local_counter >= 5)
238             continue;
239
240           counter++;
241         }
242
243       /* Exit after 4 iterations.  */
244       if (counter == 96)
245         break;
246     }
247
248   printf ("Counter was %d (should be 96)\n", counter);
249
250   if (counter != 96)
251     abort ();
252
253   /* Test that C for loops still work.  */
254   test_variable = 0;
255
256   for (counter = 0; counter < 4; counter++)
257     test_variable++;
258
259   if (test_variable != 4)
260     abort ();
261
262   return 0;
263 }