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
	}

	[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;

		for (i = 0; i < count; i++)
			tmp[i] = block(cArray[i], i);


		ret = [[OFArray alloc] initWithCArray: 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;


		for (i = 0; i < count; i++) {
			if (block(cArray[i], i))
				tmp[j++] = cArray[i];

			[pool releaseObjects];
		}

		[pool release];

		ret = [OFArray arrayWithCArray: tmp
					length: j];
	} @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;

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

	cArray = [array cArray];



	pool = [[OFAutoreleasePool alloc] init];

	current = cArray[0];


	for (i = 1; i < count; i++) {
		id old = current;
		@try {
			current = [block(current, cArray[i]) retain];
			[pool releaseObjects];
		} @finally {
			[old release];
		}
	}

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

	return [current autorelease];
}
#endif

- (void)dealloc
{







<






<
|
|
<
|
>

|
|
<
<
<
<
<
<









<






<
|

>
|
|
<
|
<
|

<
<

|









<
<
|
|






|
>
>

<
>
|
>
|
|
<

|
<

|

<
<
<
<
<
|
<
|







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
{

	OFArray *ret;
	size_t count = [array count];
	id *tmp = [self allocMemoryForNItems: count
				    withSize: sizeof(id)];

	@try {

		[self enumerateObjectsUsingBlock: ^ (id object, size_t index,
		    BOOL *stop) {

			tmp[index] = block(object, index);
		}];

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






	} @finally {
		[self freeMemory: tmp];
	}

	return ret;
}

- (OFArray*)filteredArrayUsingBlock: (of_array_filter_block_t)block
{

	OFArray *ret;
	size_t count = [array count];
	id *tmp = [self allocMemoryForNItems: count
				    withSize: sizeof(id)];

	@try {

		__block size_t i = 0;

		[self enumerateObjectsUsingBlock: ^ (id object, size_t index,
		    BOOL *stop) {
			if (block(object, index))

				tmp[i++] = object;

		}];



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

	return ret;
}

- (id)reduceUsingBlock: (of_array_reduce_block_t)block
{


	size_t count = [array count];
	__block id current;

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

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


		if (index == 0) {
			current = [object retain];
			return;
		}


		@try {
			new = [block(current, object) retain];

		} @finally {
			[current release];
		}





		current = new;

	}];

	return [current autorelease];
}
#endif

- (void)dealloc
{