Some of these implementations are not as efficient as they could be (especially the ones that take an NSIndexSet as the first argument). They also don't yet support concurrent enumeration. Apple implements these using Grand Central. We could possibly have a background thread that we send these things to (or use GCD if libdispatch is available). It's not worth spawning a new thread for them, except in exceptional circumstances (and, unfortunately, we can't easily tell how expensive a single iteration of a block is. Possibly we could time one block invocation, and if it's longer than some threshold make it concurrent, but it's probably not worth the effort).
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@29176 72102866-910b-0410-8b05-ffd578937521
NSArray *a= [NSArray arrayWithObjects: @"a", @"b", @"c", nil];
FOR_IN(NSString*, o, a)
NSLog(@"%@", o);
END_FOR_IN(a)
This is equivalent to:
for (NSString *o in a)
{
NSLog(@"%@", o);
}
On clang, it will be expanded to exactly that. With GCC, it will be expanded to something equivalent to the code that Clang (or Apple GCC) would expand this to.
This is a private GNUstep header and is not intended for general use. Outside of GNUstep, please use fast enumeration directly.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@29170 72102866-910b-0410-8b05-ffd578937521
DEFINE_BLOCK_TYPE() defines a new block type.
CALL_BLOCK() calls a block.
These use the compiler's native support for blocks if it exists, but otherwise implement the lower-level version. Note that the structure defined by the fall-back versions is NOT a complete definition of the block layout, and copies of this structure should never be instantiated.
This does not allow non-blocks-aware compiles (like GCC) to create blocks, but it does allow them to use blocks. This means that we can implement things like NSArray's -enumerateObjectsUsingBlock: without breaking GCC compatibility. To do so, you'd first need to declare a block type in the header, like this:
DEFINE_BLOCK_TYPE(GSEnumeratorBlock, void, id, NSUInteger, BOOL*);
Then declare the method like this:
- (void)enumerateObjectsUsingBlock: (GSEnumeratorBlock)aBlock;
Finally, implement it like this:
- (void)enumerateObjectsUsingBlock: (GSEnumeratorBlock)aBlock
{
NSUInteger count = 0;
BOOL shouldStop = NO;
for (obj in self)
{
CALL_BLOCK(aBlock, obj, count++, &shouldStop);
if (shouldStop)
{
return;
}
}
}
If you compile this with clang -fblocks then it will work using Clang's native support for blocks. If you compile it with GCC or clang without -fblocks then it will use the other version. Note that this example uses fast enumeration, so will only compile with clang. A proper GNUstep implementation should have some fall-back code for primitive compilers that don't support this either.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@29169 72102866-910b-0410-8b05-ffd578937521
Any blocks will have their isa pointer set to the two classes statically allocated in libobjc, but these classes can't be used for message lookup (or introspection) until after the call. This means that you can't send messages to blocks until after NSObject's +load method has been called. This shouldn't be a problem in most code, but if you use __attribute__((constructor)) instead of a +load method then be careful about sending messages to blocks (you can still call them as normal).
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@29144 72102866-910b-0410-8b05-ffd578937521
and correct some formatting.
* Source/synchronization.m: Fix @synchronize support on
Windows. The __weak__ attribute doesn't work on Windows.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@29140 72102866-910b-0410-8b05-ffd578937521
where menu positions in GUI programs would appear not persistent.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@29064 72102866-910b-0410-8b05-ffd578937521