ObjFW  Check-in [f9b3ec49f8]

Overview
Comment:Improve methods using blocks in OFArray.

Mutations during enumerations using blocks are now always detected,
even for methods such as -[reduceWithBlock:].

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: f9b3ec49f870aed219ab6f5c10aa4c8ca1696c99d7a54de229fc168349d22135
User & Date: js on 2011-07-22 18:49:36
Other Links: manifest | tags
Context
2011-07-22
18:59
Rename object1 and object2 to left and right in -[reduceWithBlock:]. check-in: 030cc6df0e user: js tags: trunk
18:49
Improve methods using blocks in OFArray. check-in: f9b3ec49f8 user: js tags: trunk
18:30
Nicer fast enumeration for OFSet. check-in: e287e086c2 user: js tags: trunk
Changes

Modified src/OFArray.m from [55a42ad5b8] to [720a88390f].

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
643

644
645

646
647
648
649
650

651
652
653
654
655
656
657
658
659
660
661
662
663


664
665
666
667
668
669
670



671
672
673
674
675





676
677
678

679
680
681

682
683
684
685
686
687
688

689
690

691
692
693
694
695
696
697
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
643
644
645
646




647
648
649
650
651
652
653
654

655
656
657
658




659
660
661
662
663

664

665

666

667
668






669


670
671
672
673
674
675
676
677







-






-
-
-
+
+
-
-
+
+

-
-
+
+
-
-
-
-
-
-









-






-
-
+

+
-
-
+
+
-
-
+
-
-
+

-
-

-
+









-
-
-
-
+
+






-
+
+
+

-
-
-
-
+
+
+
+
+
-

-
+
-

-
+

-
-
-
-
-
-
+
-
-
+







	}

	[pool release];
}

- (OFArray*)mappedArrayUsingBlock: (of_array_map_block_t)block
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFArray *ret;
	size_t count = [array count];
	id *tmp = [self allocMemoryForNItems: count
				    withSize: sizeof(id)];

	@try {
		id *cArray = [array cArray];
		size_t i;

		[self enumerateObjectsUsingBlock: ^ (id object, size_t index,
		    BOOL *stop) {
		for (i = 0; i < count; i++)
			tmp[i] = block(cArray[i], i);
			tmp[index] = block(object, index);
		}];

		ret = [[OFArray alloc] initWithCArray: tmp
					       length: count];
		ret = [OFArray arrayWithCArray: tmp
					length: count];

		@try {
			[pool release];
		} @finally {
			[ret autorelease];
		}
	} @finally {
		[self freeMemory: tmp];
	}

	return ret;
}

- (OFArray*)filteredArrayUsingBlock: (of_array_filter_block_t)block
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFArray *ret;
	size_t count = [array count];
	id *tmp = [self allocMemoryForNItems: count
				    withSize: sizeof(id)];

	@try {
		id *cArray = [array cArray];
		size_t i, j = 0;
		__block size_t i = 0;

		[self enumerateObjectsUsingBlock: ^ (id object, size_t index,
		for (i = 0; i < count; i++) {
			if (block(cArray[i], i))
		    BOOL *stop) {
			if (block(object, index))
				tmp[j++] = cArray[i];

				tmp[i++] = object;
			[pool releaseObjects];
		}
		}];

		[pool release];

		ret = [OFArray arrayWithCArray: tmp
					length: j];
					length: i];
	} @finally {
		[self freeMemory: tmp];
	}

	return ret;
}

- (id)reduceUsingBlock: (of_array_reduce_block_t)block
{
	OFAutoreleasePool *pool;
	id *cArray;
	size_t i, count = [array count];
	id current;
	size_t count = [array count];
	__block id current;

	if (count == 0)
		return nil;
	if (count == 1)
		return [[[self firstObject] retain] autorelease];

	cArray = [array cArray];
	[self enumerateObjectsUsingBlock: ^ (id object, size_t index,
	    BOOL *stop) {
		id new;

	pool = [[OFAutoreleasePool alloc] init];
	current = cArray[0];

	for (i = 1; i < count; i++) {
		if (index == 0) {
			current = [object retain];
			return;
		}

		id old = current;
		@try {
			current = [block(current, cArray[i]) retain];
			new = [block(current, object) retain];
			[pool releaseObjects];
		} @finally {
			[old release];
			[current release];
		}
	}

	@try {
		[pool release];
	} @catch (id e) {
		[current release];
		current = new;
		@throw e;
	}
	}];

	return [current autorelease];
}
#endif

- (void)dealloc
{