forked from snej/MYUtilities
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathCollectionUtils.h
176 lines (137 loc) · 5.96 KB
/
CollectionUtils.h
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
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
//
// CollectionUtils.h
// MYUtilities
//
// Created by Jens Alfke on 1/5/08.
// Copyright 2008-2013 Jens Alfke. All rights reserved.
//
#import <Foundation/Foundation.h>
#define _MYUTILITIES_COLLECTIONUTILS_ 1
// Collection creation conveniences:
#define $array(OBJS...) ({id objs[]={OBJS}; \
[NSArray arrayWithObjects: objs count: sizeof(objs)/sizeof(id)];})
#define $marray(OBJS...) ({id objs[]={OBJS}; \
[NSMutableArray arrayWithObjects: objs count: sizeof(objs)/sizeof(id)];})
#define $dict(PAIRS...) ({_dictpair pairs[]={PAIRS}; \
_dictof(pairs,sizeof(pairs)/sizeof(_dictpair));})
#define $mdict(PAIRS...) ({_dictpair pairs[]={PAIRS}; \
_mdictof(pairs,sizeof(pairs)/sizeof(_dictpair));})
#define $object(VAL) ({__typeof(VAL) v=(VAL); _box(&v,@encode(__typeof(v)));})
// Apply a selector to each array element, returning an array of the results:
// (See also -[NSArray my_map:], which is more general but requires block support)
NSArray* $apply( NSArray *src, SEL selector, id defaultValue );
NSArray* $applyKeyPath( NSArray *src, NSString *keyPath, id defaultValue );
// Object conveniences:
BOOL $equal(id obj1, id obj2); // Like -isEqual: but works even if either/both are nil
NSString* $string( const char *utf8Str );
#define $sprintf(FORMAT, ARGS... ) [NSString stringWithFormat: (FORMAT), ARGS]
#define $cast(CLASSNAME,OBJ) ((CLASSNAME*)(_cast([CLASSNAME class],(OBJ))))
#define $castNotNil(CLASSNAME,OBJ) ((CLASSNAME*)(_castNotNil([CLASSNAME class],(OBJ))))
#define $castIf(CLASSNAME,OBJ) ((CLASSNAME*)(_castIf([CLASSNAME class],(OBJ))))
#define $castArrayOf(ITEMCLASSNAME,OBJ) _castArrayOf([ITEMCLASSNAME class],(OBJ))
#define $castIfArrayOf(ITEMCLASSNAME,OBJ) _castIfArrayOf([ITEMCLASSNAME class],(OBJ))
void setObj( id *var, id value );
BOOL ifSetObj( id *var, id value );
void setObjCopy( id *var, id valueToCopy );
BOOL ifSetObjCopy( id *var, id value );
static inline void setString( NSString **var, NSString *value ) {setObjCopy(var,value);}
static inline BOOL ifSetString( NSString **var, NSString *value ) {return ifSetObjCopy(var,value);}
BOOL kvSetObj( id owner, NSString *property, id *varPtr, id value );
BOOL kvSetObjCopy( id owner, NSString *property, id *varPtr, id value );
BOOL kvSetSet( id owner, NSString *property, NSMutableSet *set, NSSet *newSet );
BOOL kvAddToSet( id owner, NSString *property, NSMutableSet *set, id objToAdd );
BOOL kvRemoveFromSet( id owner, NSString *property, NSMutableSet *set, id objToRemove );
// Use this to prevent an object from being dealloced in this scope, even if you call something
// that releases it.
#if __has_feature(objc_arc)
#define MYDeferDealloc(OBJ) __unused id _deferDealloc_##__LINE__ = (OBJ)
#else
#define MYDeferDealloc(OBJ) [[(OBJ) retain] autorelease]
#endif
#define $true ((NSNumber*)kCFBooleanTrue)
#define $false ((NSNumber*)kCFBooleanFalse)
#define $null [NSNull null]
@interface NSObject (MYUtils)
- (NSString*) my_compactDescription;
@end
@interface NSArray (MYUtils)
- (BOOL) my_containsObjectIdenticalTo: (id)object;
- (NSArray*) my_arrayByApplyingSelector: (SEL)selector;
- (NSArray*) my_arrayByApplyingSelector: (SEL)selector withObject: (id)object;
#if NS_BLOCKS_AVAILABLE
- (NSArray*) my_map: (id (^)(id obj))block;
- (NSArray*) my_filter: (int (^)(id obj))block;
#endif
@end
#if NS_BLOCKS_AVAILABLE
@interface NSMutableArray (MYUtils)
- (void) my_removeMatching: (int (^)(id obj))block;
@end
#endif
#if NS_BLOCKS_AVAILABLE && MY_ENABLE_ENUMERATOR_MAP
@interface NSEnumerator (MYUtils)
- (NSEnumerator*) my_map: (id (^)(id obj))block;
@end
#endif
@interface NSSet (MYUtils)
+ (NSSet*) my_unionOfSet: (NSSet*)set1 andSet: (NSSet*)set2;
+ (NSSet*) my_intersectionOfSet: (NSSet*)set1 andSet: (NSSet*)set2;
+ (NSSet*) my_differenceOfSet: (NSSet*)set1 andSet: (NSSet*)set2;
@end
#if NS_BLOCKS_AVAILABLE
@interface NSDictionary (MYUtils)
- (NSDictionary*) my_dictionaryByUpdatingValues: (id (^)(id key, id value))block;
@end
#endif
@interface NSData (MYUtils)
- (NSString*) my_UTF8ToString;
@end
// Compatibility declarations to allow NSArray/NSDictionary subscripting in iOS with Xcode 4.4.
// The compiler needs to see declarations of these methods to make the class subscriptable, but
// the iOS 5.1 SDK doesn't contain them on NSArray/NSDictionary. It appears it isn't necessary
// to actually implement these methods, though...
#if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED < 60000)
@interface NSArray (PreiOS6)
- (id)objectAtIndexedSubscript:(NSUInteger)index;
@end
@interface NSMutableArray (PreiOS6)
- (void)setObject: (id)object atIndexedSubscript:(NSUInteger)index;
@end
@interface NSDictionary (PreiOS6)
- (id)objectForKeyedSubscript:(id)key;
@end
@interface NSMutableDictionary (PreiOS6)
- (void)setObject: (id)object forKeyedSubscript:(id)key;
@end
#endif
#ifdef GNUSTEP
#define kCFBooleanTrue ([NSNumber numberWithBool: YES])
#define kCFBooleanFalse ([NSNumber numberWithBool: NO])
#endif
#pragma mark -
#pragma mark FOREACH:
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
#define foreach(VAR,ARR) for(VAR in ARR)
#else
struct foreachstate {NSArray *array; unsigned n, i;};
static inline struct foreachstate _initforeach( NSArray *arr ) {
struct foreachstate s;
s.array = arr;
s.n = [arr count];
s.i = 0;
return s;
}
#define foreach(VAR,ARR) for( struct foreachstate _s = _initforeach((ARR)); \
_s.i<_s.n && ((VAR)=[_s.array objectAtIndex: _s.i], YES); \
_s.i++ )
#endif
// Internals (don't use directly)
typedef id _dictpair[2];
NSDictionary* _dictof(const _dictpair*, size_t count);
NSMutableDictionary* _mdictof(const _dictpair[], size_t count);
id _box(const void *value, const char *encoding);
id _cast(Class,id);
id _castNotNil(Class,id);
id _castIf(Class,id);
NSArray* _castArrayOf(Class,NSArray*);
NSArray* _castIfArrayOf(Class,NSArray*);