ObjFW  Check-in [daae7ffbf3]

Overview
Comment:Make OFEnumerator more general, implement it for OFArray & OFDictionary.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: daae7ffbf3f21f8cf70ee5dbe7917ecb3e20a3e5ba7d160089eda515c81edb32
User & Date: js on 2010-01-30 15:47:44
Other Links: manifest | tags
Context
2010-01-30
18:29
Change how the Unicode table is stored. check-in: 13f2a20288 user: js tags: trunk
15:47
Make OFEnumerator more general, implement it for OFArray & OFDictionary. check-in: daae7ffbf3 user: js tags: trunk
14:26
Don't define methods unavailable on Windows. check-in: c9e9ea561c user: js tags: trunk
Changes

Modified src/OFArray.h from [bd1813c90a] to [f31644bdce].

8
9
10
11
12
13
14

15
16
17
18
19
20
21
 * Q Public License 1.0, which can be found in the file LICENSE included in
 * the packaging of this file.
 */

#include <stdarg.h>

#import "OFObject.h"

#import "OFFastEnumeration.h"

@class OFDataArray;
@class OFString;

/**
 * The OFArray class is a class for storing objects in an array.







>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 * Q Public License 1.0, which can be found in the file LICENSE included in
 * the packaging of this file.
 */

#include <stdarg.h>

#import "OFObject.h"
#import "OFEnumerator.h"
#import "OFFastEnumeration.h"

@class OFDataArray;
@class OFString;

/**
 * The OFArray class is a class for storing objects in an array.
138
139
140
141
142
143
144


















145
146
147
/**
 * Creates a string by joining all objects of the array.
 *
 * \param separator The string with which the objects should be joined
 * \return A string containing all objects joined by the separator
 */
- (OFString*)componentsJoinedByString: (OFString*)separator;


















@end

#import "OFMutableArray.h"







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/**
 * Creates a string by joining all objects of the array.
 *
 * \param separator The string with which the objects should be joined
 * \return A string containing all objects joined by the separator
 */
- (OFString*)componentsJoinedByString: (OFString*)separator;

/**
 * \return An OFEnumerator to enumarate through the array's objects
 */
- (OFEnumerator*)enumerator;
@end

@interface OFArrayEnumerator: OFEnumerator
{
	OFDataArray   *array;
	size_t	      count;
	unsigned long mutations;
	unsigned long *mutations_ptr;
	size_t	      pos;
}

- initWithDataArray: (OFDataArray*)data
   mutationsPointer: (unsigned long*)mutations_ptr;
@end

#import "OFMutableArray.h"

Modified src/OFArray.m from [fbda4dec52] to [56c9de1a04].

297
298
299
300
301
302
303







304
305
306
307
308
309
310
311
312
313
314
315
316
317





































	state->state = count;
	state->itemsPtr = [array cArray];
	state->mutationsPtr = (unsigned long*)self;

	return count;
}








- (void)dealloc
{
	OFObject **objs = [array cArray];
	size_t i, count = [array count];

	for (i = 0; i < count; i++)
		[objs[i] release];

	[array release];

	[super dealloc];
}
@end











































>
>
>
>
>
>
>














>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360

	state->state = count;
	state->itemsPtr = [array cArray];
	state->mutationsPtr = (unsigned long*)self;

	return count;
}

- (OFEnumerator*)enumerator
{
	return [[[OFArrayEnumerator alloc]
	    initWithDataArray: array
	     mutationsPointer: NULL] autorelease];
}

- (void)dealloc
{
	OFObject **objs = [array cArray];
	size_t i, count = [array count];

	for (i = 0; i < count; i++)
		[objs[i] release];

	[array release];

	[super dealloc];
}
@end

@implementation OFArrayEnumerator
- initWithDataArray: (OFDataArray*)array_
   mutationsPointer: (unsigned long*)mutations_ptr_;
{
	self = [super init];

	array = array_;
	count = [array_ count];
	mutations = *mutations_ptr_;
	mutations_ptr = mutations_ptr_;

	return self;
}

- (id)nextObject
{
	if (mutations_ptr != NULL && *mutations_ptr != mutations)
		@throw [OFEnumerationMutationException newWithClass: isa];

	if (pos < count)
		return *(OFObject**)[array itemAtIndex: pos++];

	return nil;
}

- reset
{
	if (mutations_ptr != NULL && *mutations_ptr != mutations)
		@throw [OFEnumerationMutationException newWithClass: isa];

	pos = 0;

	return self;
}
@end

Modified src/OFDictionary.h from [f7ca41c6f4] to [520f646873].

8
9
10
11
12
13
14

15
16
17
18
19
20
21
 * Q Public License 1.0, which can be found in the file LICENSE included in
 * the packaging of this file.
 */

#include <stdarg.h>

#import "OFObject.h"

#import "OFFastEnumeration.h"

@class OFArray;

struct of_dictionary_bucket
{
	OFObject <OFCopying> *key;







>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 * Q Public License 1.0, which can be found in the file LICENSE included in
 * the packaging of this file.
 */

#include <stdarg.h>

#import "OFObject.h"
#import "OFEnumerator.h"
#import "OFFastEnumeration.h"

@class OFArray;

struct of_dictionary_bucket
{
	OFObject <OFCopying> *key;
141
142
143
144
145
146
147










148
149
150



















151
 */
- (id)objectForKey: (OFObject <OFCopying>*)key;

/**
 * \return The number of objects in the dictionary
 */
- (size_t)count;










@end

#import "OFEnumerator.h"



















#import "OFMutableDictionary.h"







>
>
>
>
>
>
>
>
>
>


|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
 */
- (id)objectForKey: (OFObject <OFCopying>*)key;

/**
 * \return The number of objects in the dictionary
 */
- (size_t)count;

/**
 * \returns An OFEnumerator to enumerate through the dictionary's objects
 */
- (OFEnumerator*)objectEnumerator;

/**
 * \return An OFEnumerator to enumerate through the dictionary's keys
 */
- (OFEnumerator*)keyEnumerator;
@end

@interface OFDictionaryEnumerator: OFEnumerator
{
	struct of_dictionary_bucket *data;
	size_t			    size;
	unsigned long		    mutations;
	unsigned long		    *mutations_ptr;
	size_t			    pos;
}

-     initWithData: (struct of_dictionary_bucket*)data
	      size: (size_t)size
  mutationsPointer: (unsigned long*)mutations_ptr;
@end

@interface OFDictionaryObjectEnumerator: OFDictionaryEnumerator
@end

@interface OFDictionaryKeyEnumerator: OFDictionaryEnumerator
@end

#import "OFMutableDictionary.h"

Modified src/OFDictionary.m from [7f7aa6e96f] to [c81ffb2e26].

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#import "OFArray.h"
#import "OFAutoreleasePool.h"
#import "OFExceptions.h"
#import "OFMacros.h"

#define BUCKET_SIZE sizeof(struct of_dictionary_bucket)

/* References for static linking */
void _references_to_categories_of_OFDictionary()
{
	_OFEnumerator_reference = 1;
}

@implementation OFDictionary
+ dictionary;
{
	return [[[self alloc] init] autorelease];
}

+ dictionaryWithDictionary: (OFDictionary*)dict







<
<
<
<
<
<







18
19
20
21
22
23
24






25
26
27
28
29
30
31
#import "OFArray.h"
#import "OFAutoreleasePool.h"
#import "OFExceptions.h"
#import "OFMacros.h"

#define BUCKET_SIZE sizeof(struct of_dictionary_bucket)







@implementation OFDictionary
+ dictionary;
{
	return [[[self alloc] init] autorelease];
}

+ dictionaryWithDictionary: (OFDictionary*)dict
527
528
529
530
531
532
533
















534
535
536
537
538
539
540
	}

	state->itemsPtr = objects;
	state->mutationsPtr = (unsigned long*)self;

	return i;
}

















- (void)dealloc
{
	size_t i;

	for (i = 0; i < size; i++) {
		if (data[i].key != nil) {







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
	}

	state->itemsPtr = objects;
	state->mutationsPtr = (unsigned long*)self;

	return i;
}

- (OFEnumerator*)objectEnumerator
{
	return [[[OFDictionaryObjectEnumerator alloc]
		initWithData: data
			size: size
	    mutationsPointer: NULL] autorelease];
}

- (OFEnumerator*)keyEnumerator
{
	return [[[OFDictionaryKeyEnumerator alloc]
		initWithData: data
			size: size
	    mutationsPointer: NULL] autorelease];
}

- (void)dealloc
{
	size_t i;

	for (i = 0; i < size; i++) {
		if (data[i].key != nil) {
570
571
572
573
574
575
576
























































	}

	OF_HASH_FINALIZE(hash);

	return hash;
}
@end































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
	}

	OF_HASH_FINALIZE(hash);

	return hash;
}
@end

@implementation OFDictionaryEnumerator
-     initWithData: (struct of_dictionary_bucket*)data_
	      size: (size_t)size_
  mutationsPointer: (unsigned long*)mutations_ptr_
{
	self = [super init];

	data = data_;
	size = size_;
	mutations = *mutations_ptr_;
	mutations_ptr = mutations_ptr_;

	return self;
}

- reset
{
	if (mutations_ptr != NULL && *mutations_ptr != mutations)
		@throw [OFEnumerationMutationException newWithClass: isa];

	pos = 0;

	return self;
}
@end

@implementation OFDictionaryObjectEnumerator
- (id)nextObject
{
	if (mutations_ptr != NULL && *mutations_ptr != mutations)
		@throw [OFEnumerationMutationException newWithClass: isa];

	for (; pos < size && data[pos].key == nil; pos++);

	if (pos < size)
		return data[pos++].object;
	else
		return nil;
}
@end

@implementation OFDictionaryKeyEnumerator
- (id)nextObject
{
	if (mutations_ptr != NULL && *mutations_ptr != mutations)
		@throw [OFEnumerationMutationException newWithClass: isa];

	for (; pos < size && data[pos].key == nil; pos++);

	if (pos < size)
		return data[pos++].key;
	else
		return nil;
}
@end

Modified src/OFEnumerator.h from [63f8eed5f2] to [1e45836bf9].

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/*
 * Copyright (c) 2008 - 2009
 *   Jonathan Schleifer <js@webkeks.org>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE included in
 * the packaging of this file.
 */

#import "OFObject.h"
#import "OFDictionary.h"

/**
 * An enumerator pair combines a key and its object in a single struct.
 */
typedef struct __of_enumerator_pair {
	/// The key
	id	 key;
	/// The object for the key
	id	 object;
} of_enumerator_pair_t;

extern int _OFEnumerator_reference;

/**
 * The OFEnumerator class provides methods to enumerate through objects.
 */
@interface OFEnumerator: OFObject
{
	struct of_dictionary_bucket *data;
	size_t			    size;
	size_t			    pos;
}

- initWithData: (struct of_dictionary_bucket*)data
	  size: (size_t)size;

/**
 * \return A struct containing the next key and object
 */
- (of_enumerator_pair_t)nextKeyObjectPair;

/**
 * Resets the enumerator, so the next call to nextObject returns the first
 * again.
 */
- reset;
@end

/**
 * The OFEnumerator category adds functions to get an interator to OFDictionary.
 */
@interface OFDictionary (OFEnumerator)
/**
 * Creates an OFEnumerator for the dictionary.
 *
 * It will copy the data of the OFDictionary so that OFEnumerator will always
 * operate on the data that was present when it was created. If you changed the
 * OFDictionary and want to operate on the new data, you need to create a new
 * OFEnumerator, as using reset will only reset the OFEnumerator, but won't
 * update the data. It will also retain the data inside the OFDictionary so the
 * OFEnumerator still works after you released the OFDictionary. Thus, if you
 * want to get rid of the objects in the OFDictionary, you also need to release
 * the OFEnumerator.
 *
 * \return An OFEnumerator for the OFDictionary
 */
- (OFEnumerator*)enumerator;
@end












<


<
<
<
<
<
<
<
<
<
<
<
<
|

|
<
<
<
<
<
<
<
<
<

|

|



|



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
1
2
3
4
5
6
7
8
9
10
11
12

13
14












15
16
17









18
19
20
21
22
23
24
25
26
27
28





















/*
 * Copyright (c) 2008 - 2009
 *   Jonathan Schleifer <js@webkeks.org>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE included in
 * the packaging of this file.
 */

#import "OFObject.h"


/**












 * The OFEnumerator class provides methods to enumerate through collections.
 */
@interface OFEnumerator: OFObject {}









/**
 * \return The next object
 */
- (id)nextObject;

/**
 * Resets the enumerator, so the next call to nextObject returns the first
 * object again.
 */
- reset;
@end





















Modified src/OFEnumerator.m from [0155b17e2f] to [654fa1e987].

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
 * Q Public License 1.0, which can be found in the file LICENSE included in
 * the packaging of this file.
 */

#include "config.h"

#import "OFEnumerator.h"
#import "OFDictionary.h"
#import "OFExceptions.h"

/* Reference for static linking */
int _OFEnumerator_reference;

@implementation OFEnumerator
- init
{

	@throw [OFNotImplementedException newWithClass: isa
					      selector: _cmd];
}

- initWithData: (struct of_dictionary_bucket*)data_
	  size: (size_t)size_
{
	size_t i;

	self = [super init];

	size = size_;
	data = [self allocMemoryForNItems: size
				 withSize: sizeof(struct of_dictionary_bucket)];

	for (i = 0; i < size; i++) {
		if (data_[i].key != nil) {
			data[i].key = [data_[i].key copy];
			data[i].object = [data_[i].object retain];
		} else
			data[i].key = nil;
	}

	return self;
}

- (void)dealloc
{
	size_t i;

	for (i = 0; i < size; i++) {
		if (data[i].key != nil) {
			[data[i].key release];
			[data[i].object release];
		}
	}

	[super dealloc];
}

- (of_enumerator_pair_t)nextKeyObjectPair
{
	of_enumerator_pair_t next;

	for (; pos < size && data[pos].key == nil; pos++);

	if (pos < size) {
		next.key = data[pos].key;
		next.object = data[pos].object;
		pos++;
	} else {
		next.key = nil;
		next.object = nil;
	}

	return next;
}

- reset
{
	pos = 0;

	return self;
}
@end

@implementation OFDictionary (OFEnumerator)
- (OFEnumerator*)enumerator
{
	return [[[OFEnumerator alloc] initWithData: data
					      size: size] autorelease];
}
@end







<


<
<
<



>
|
|
|
<
<
<
<
<
<
|
|
<
<
<

<
<
<
<
<
<
<
|
<
<
|
<
<
<
|
<
<
<
<
<
<
|
<


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


<
|
<
<
<
|
<
<
<
<
<


8
9
10
11
12
13
14

15
16



17
18
19
20
21
22
23






24
25



26







27


28



29






30

31
32


















33
34

35



36





37
38
 * Q Public License 1.0, which can be found in the file LICENSE included in
 * the packaging of this file.
 */

#include "config.h"

#import "OFEnumerator.h"

#import "OFExceptions.h"




@implementation OFEnumerator
- init
{
	if (isa == [OFEnumerator class])
		@throw [OFNotImplementedException newWithClass: isa
						      selector: _cmd];







	return [super init];
}











- (id)nextObject


{



	@throw [OFNotImplementedException newWithClass: isa






					      selector: _cmd];

}



















- reset
{

	@throw [OFNotImplementedException newWithClass: isa



					      selector: _cmd];





}
@end

Modified src/OFMutableArray.m from [cea77e21a1] to [1f2b88f8de].

236
237
238
239
240
241
242







243

	state->state = count;
	state->itemsPtr = [array cArray];
	state->mutationsPtr = &mutations;

	return count;
}







@end







>
>
>
>
>
>
>

236
237
238
239
240
241
242
243
244
245
246
247
248
249
250

	state->state = count;
	state->itemsPtr = [array cArray];
	state->mutationsPtr = &mutations;

	return count;
}

- (OFEnumerator*)enumerator
{
	return [[[OFArrayEnumerator alloc]
	    initWithDataArray: array
	     mutationsPointer: &mutations] autorelease];
}
@end

Modified src/OFMutableDictionary.m from [6f1a880dde] to [a965448013].

183
184
185
186
187
188
189
















190
	}

	state->itemsPtr = objects;
	state->mutationsPtr = &mutations;

	return i;
}
















@end







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
	}

	state->itemsPtr = objects;
	state->mutationsPtr = &mutations;

	return i;
}

- (OFEnumerator*)objectEnumerator
{
	return [[[OFDictionaryObjectEnumerator alloc]
		initWithData: data
			size: size
	    mutationsPointer: &mutations] autorelease];
}

- (OFEnumerator*)keyEnumerator
{
	return [[[OFDictionaryKeyEnumerator alloc]
		initWithData: data
			size: size
	    mutationsPointer: &mutations] autorelease];
}
@end

Modified tests/OFArray.m from [64707b9f4f] to [a4eb61b01c].

28
29
30
31
32
33
34




35
36
37
38
39
40
41

void
array_tests()
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFArray *a[2];
	OFMutableArray *m[2];





	TEST(@"+[array]", (m[0] = [OFMutableArray array]))

	TEST(@"+[arrayWithObjects:]",
	    (a[0] = [OFArray arrayWithObjects: @"Foo", @"Bar", @"Baz", nil]))

	TEST(@"+[arrayWithCArray:]", (a[1] = [OFArray arrayWithCArray: c_ary]))







>
>
>
>







28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

void
array_tests()
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFArray *a[2];
	OFMutableArray *m[2];
	OFEnumerator *enumerator;
	id obj;
	BOOL ok;
	size_t i;

	TEST(@"+[array]", (m[0] = [OFMutableArray array]))

	TEST(@"+[arrayWithObjects:]",
	    (a[0] = [OFArray arrayWithObjects: @"Foo", @"Bar", @"Baz", nil]))

	TEST(@"+[arrayWithCArray:]", (a[1] = [OFArray arrayWithCArray: c_ary]))
114
115
116
117
118
119
120
121

122





123



124










125


126
127
128
129
130
131
132
	EXPECT_EXCEPTION(@"Detect out of range in -[removeNItems:]",
	    OFOutOfRangeException, [m[0] removeNObjects: [m[0] count] + 1])

	a[1] = [OFArray arrayWithObjects: @"foo", @"bar", @"baz", nil];
	TEST(@"-[componentsJoinedByString:]",
	    [[a[1] componentsJoinedByString: @" "] isEqual: @"foo bar baz"])

#ifdef OF_HAVE_FAST_ENUMERATION

	size_t i = 0;





	BOOL ok = YES;














	m[0] = [[a[0] mutableCopy] autorelease];



	for (OFString *s in m[0]) {
		if (![s isEqual: c_ary[i]])
			ok = NO;
		[m[0] replaceObjectAtIndex: i
				withObject: @""];
		i++;







|
>
|
>
>
>
>
>
|
>
>
>
|
>
>
>
>
>
>
>
>
>
>

>
>







118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
	EXPECT_EXCEPTION(@"Detect out of range in -[removeNItems:]",
	    OFOutOfRangeException, [m[0] removeNObjects: [m[0] count] + 1])

	a[1] = [OFArray arrayWithObjects: @"foo", @"bar", @"baz", nil];
	TEST(@"-[componentsJoinedByString:]",
	    [[a[1] componentsJoinedByString: @" "] isEqual: @"foo bar baz"])

	m[0] = [[a[0] mutableCopy] autorelease];
	ok = YES;
	i = 0;

	TEST(@"-[enumerator]", (enumerator = [m[0] enumerator]))

	while ((obj = [enumerator nextObject]) != nil) {
		if (![obj isEqual: c_ary[i]])
			ok = NO;
		[m[0] replaceObjectAtIndex: i
				withObject: @""];
		i++;
	}

	TEST(@"OFEnumerator's -[nextObject]", ok)

	[enumerator reset];
	[m[0] removeObjectAtIndex: 0];

	EXPECT_EXCEPTION(@"Detection of mutation during enumeration",
	    OFEnumerationMutationException, [enumerator nextObject])

#ifdef OF_HAVE_FAST_ENUMERATION
	m[0] = [[a[0] mutableCopy] autorelease];
	ok = YES;
	i = 0;

	for (OFString *s in m[0]) {
		if (![s isEqual: c_ary[i]])
			ok = NO;
		[m[0] replaceObjectAtIndex: i
				withObject: @""];
		i++;

Modified tests/OFDictionary.m from [a0ff0ff918] to [81a0cd4f6f].

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

52
53
54
55
56
57
58
59
60

61








62
63
64
65
66
67
68
};

void
dictionary_tests()
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFMutableDictionary *dict = [OFMutableDictionary dictionary], *dict2;
	OFEnumerator *enumerator;
	of_enumerator_pair_t pair[3];
	OFArray *akeys, *avalues;

	[dict setObject: values[0]
		 forKey: keys[0]];
	[dict setObject: values[1]
		 forKey: keys[1]];

	TEST(@"-[objectForKey:]",
	    [[dict objectForKey: keys[0]] isEqual: values[0]] &&
	    [[dict objectForKey: keys[1]] isEqual: values[1]] &&
	    [dict objectForKey: @"key3"] == nil)

	TEST(@"-[enumerator]", (enumerator = [dict enumerator]))


	pair[0] = [enumerator nextKeyObjectPair];
	pair[1] = [enumerator nextKeyObjectPair];
	pair[2] = [enumerator nextKeyObjectPair];
	TEST(@"OFEnumerator's -[nextKeyObjectPair]",
	    [pair[0].key isEqual: keys[0]] &&
	    [pair[0].object isEqual: values[0]] &&
	    [pair[1].key isEqual: keys[1]] &&
	    [pair[1].object isEqual: values[1]] &&

	    pair[2].key == nil && pair[2].object == nil)









#ifdef OF_HAVE_FAST_ENUMERATION
	size_t i = 0;
	BOOL ok = YES;

	for (OFString *key in dict) {
		if (![key isEqual: keys[i]])







|
<












|
>

<
<
<
|
|
|
|
|
>
|
>
>
>
>
>
>
>
>







30
31
32
33
34
35
36
37

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
};

void
dictionary_tests()
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFMutableDictionary *dict = [OFMutableDictionary dictionary], *dict2;
	OFEnumerator *key_enum, *obj_enum;

	OFArray *akeys, *avalues;

	[dict setObject: values[0]
		 forKey: keys[0]];
	[dict setObject: values[1]
		 forKey: keys[1]];

	TEST(@"-[objectForKey:]",
	    [[dict objectForKey: keys[0]] isEqual: values[0]] &&
	    [[dict objectForKey: keys[1]] isEqual: values[1]] &&
	    [dict objectForKey: @"key3"] == nil)

	TEST(@"-[keyEnumerator]", (key_enum = [dict keyEnumerator]))
	TEST(@"-[objectEnumerator]", (obj_enum = [dict objectEnumerator]))




	TEST(@"OFEnumerator's -[nextObject]",
	    [[key_enum nextObject] isEqual: keys[0]] &&
	    [[obj_enum nextObject] isEqual: values[0]] &&
	    [[key_enum nextObject] isEqual: keys[1]] &&
	    [[obj_enum nextObject] isEqual: values[1]] &&
	    [key_enum nextObject] == nil && [obj_enum nextObject] == nil)

	[key_enum reset];
	[dict removeObjectForKey: keys[0]];

	EXPECT_EXCEPTION(@"Detection of mutation during enumeration",
	    OFEnumerationMutationException, [key_enum nextObject]);

	[dict setObject: values[0]
		 forKey: keys[0]];

#ifdef OF_HAVE_FAST_ENUMERATION
	size_t i = 0;
	BOOL ok = YES;

	for (OFString *key in dict) {
		if (![key isEqual: keys[i]])