OSDN Git Service

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