5
5
#define CF_BRIDGED_TYPE (T ) __attribute__((objc_bridge(T)))
6
6
#define CF_BRIDGED_MUTABLE_TYPE (T ) __attribute__((objc_bridge_mutable(T)))
7
7
typedef CF_BRIDGED_TYPE (id ) void * CFTypeRef;
8
+ typedef unsigned long long CFTypeID;
8
9
typedef signed char BOOL ;
9
10
typedef unsigned char Boolean;
10
11
typedef signed long CFIndex;
@@ -21,6 +22,8 @@ typedef struct CF_BRIDGED_MUTABLE_TYPE(CFRunLoopRef) __CFRunLoop * CFRunLoopRef;
21
22
22
23
extern const CFAllocatorRef kCFAllocatorDefault;
23
24
typedef struct _NSZone NSZone ;
25
+ CFTypeID CFGetTypeID (CFTypeRef cf);
26
+ CFTypeID CFArrayGetTypeID ();
24
27
CFMutableArrayRef CFArrayCreateMutable (CFAllocatorRef allocator, CFIndex capacity);
25
28
extern void CFArrayAppendValue (CFMutableArrayRef theArray, const void *value);
26
29
CFArrayRef CFArrayCreate (CFAllocatorRef allocator, const void **values, CFIndex numValues);
@@ -29,6 +32,7 @@ CFIndex CFArrayGetCount(CFArrayRef theArray);
29
32
typedef const struct CF_BRIDGED_TYPE (NSDictionary ) __CFDictionary * CFDictionaryRef;
30
33
typedef struct CF_BRIDGED_MUTABLE_TYPE (NSMutableDictionary ) __CFDictionary * CFMutableDictionaryRef;
31
34
35
+ CFTypeID CFDictionaryGetTypeID ();
32
36
CFDictionaryRef CFDictionaryCreate (CFAllocatorRef allocator, const void **keys, const void **values, CFIndex numValues);
33
37
CFDictionaryRef CFDictionaryCreateCopy (CFAllocatorRef allocator, CFDictionaryRef theDict);
34
38
CFDictionaryRef CFDictionaryCreateMutableCopy (CFAllocatorRef allocator, CFIndex capacity, CFDictionaryRef theDict);
@@ -135,6 +139,8 @@ __attribute__((objc_root_class))
135
139
136
140
namespace WTF {
137
141
142
+ void WTFCrash (void );
143
+
138
144
template<typename T> class RetainPtr;
139
145
template<typename T> RetainPtr<T> adoptNS (T*);
140
146
template<typename T> RetainPtr<T> adoptCF (T);
@@ -273,11 +279,163 @@ inline CFTypeRef bridge_cast(NSObject *object)
273
279
return (__bridge CFTypeRef)object;
274
280
}
275
281
282
+ inline id bridge_id_cast (CFTypeRef object)
283
+ {
284
+ return (__bridge id )object;
285
+ }
286
+
287
+ inline RetainPtr<id > bridge_id_cast (RetainPtr<CFTypeRef>&& object)
288
+ {
289
+ #if __has_feature(objc_arc)
290
+ return adoptNS ((__bridge_transfer id )object.leakRef ());
291
+ #else
292
+ return adoptNS ((__bridge id )object.leakRef ());
293
+ #endif
294
+ }
295
+
296
+ template <typename ExpectedType>
297
+ struct ObjCTypeCastTraits {
298
+ public:
299
+ static bool isType (id object) { return [object isKindOfClass: [ExpectedType class ]]; }
300
+
301
+ template <typename ArgType>
302
+ static bool isType (const ArgType *object) { return [object isKindOfClass: [ExpectedType class ]]; }
303
+ };
304
+
305
+ template <typename ExpectedType, typename ArgType>
306
+ inline bool is_objc (ArgType * source)
307
+ {
308
+ return source && ObjCTypeCastTraits<ExpectedType>::isType (source);
309
+ }
310
+
311
+ template<typename T> inline T *checked_objc_cast (id object)
312
+ {
313
+ if (!object)
314
+ return nullptr ;
315
+
316
+ if (!is_objc<T>(object))
317
+ WTFCrash ();
318
+
319
+ return reinterpret_cast<T*>(object);
320
+ }
321
+
322
+ template<typename T, typename U> inline T *checked_objc_cast (U *object)
323
+ {
324
+ if (!object)
325
+ return nullptr ;
326
+
327
+ if (!is_objc<T>(object))
328
+ WTFCrash ();
329
+
330
+ return static_cast<T*>(object);
331
+ }
332
+
333
+ template<typename T, typename U> RetainPtr<T> dynamic_objc_cast (RetainPtr<U>&& object)
334
+ {
335
+ if (!is_objc<T>(object.get ()))
336
+ return nullptr ;
337
+ return adoptNS (static_cast<T*>(object.leakRef ()));
338
+ }
339
+
340
+ template<typename T> RetainPtr<T> dynamic_objc_cast (RetainPtr<id >&& object)
341
+ {
342
+ if (!is_objc<T>(object.get ()))
343
+ return nullptr ;
344
+ return adoptNS (reinterpret_cast<T*>(object.leakRef ()));
345
+ }
346
+
347
+ template<typename T, typename U> RetainPtr<T> dynamic_objc_cast (const RetainPtr<U>& object)
348
+ {
349
+ if (!is_objc<T>(object.get ()))
350
+ return nullptr ;
351
+ return static_cast<T*>(object.get ());
276
352
}
277
353
354
+ template<typename T> RetainPtr<T> dynamic_objc_cast (const RetainPtr<id >& object)
355
+ {
356
+ if (!is_objc<T>(object.get ()))
357
+ return nullptr ;
358
+ return reinterpret_cast<T*>(object.get ());
359
+ }
360
+
361
+ template<typename T> T *dynamic_objc_cast (NSObject *object)
362
+ {
363
+ if (!is_objc<T>(object))
364
+ return nullptr ;
365
+ return static_cast<T*>(object);
366
+ }
367
+
368
+ template<typename T> T *dynamic_objc_cast (id object)
369
+ {
370
+ if (!is_objc<T>(object))
371
+ return nullptr ;
372
+ return reinterpret_cast<T*>(object);
373
+ }
374
+
375
+ template <typename> struct CFTypeTrait;
376
+
377
+ template<typename T> T dynamic_cf_cast (CFTypeRef object)
378
+ {
379
+ if (!object)
380
+ return nullptr ;
381
+
382
+ if (CFGetTypeID (object) != CFTypeTrait<T>::typeID ())
383
+ return nullptr ;
384
+
385
+ return static_cast<T>(const_cast<CF_BRIDGED_TYPE (id ) void *>(object));
386
+ }
387
+
388
+ template<typename T> T checked_cf_cast (CFTypeRef object)
389
+ {
390
+ if (!object)
391
+ return nullptr ;
392
+
393
+ if (CFGetTypeID (object) != CFTypeTrait<T>::typeID ())
394
+ WTFCrash ();
395
+
396
+ return static_cast<T>(const_cast<CF_BRIDGED_TYPE (id ) void *>(object));
397
+ }
398
+
399
+ template<typename T, typename U> RetainPtr<T> dynamic_cf_cast (RetainPtr<U>&& object)
400
+ {
401
+ if (!object)
402
+ return nullptr ;
403
+
404
+ if (CFGetTypeID (object.get ()) != CFTypeTrait<T>::typeID ())
405
+ return nullptr ;
406
+
407
+ return adoptCF (static_cast<T>(const_cast<CF_BRIDGED_TYPE (id ) void *>(object.leakRef ())));
408
+ }
409
+
410
+ } // namespace WTF
411
+
412
+ #define WTF_DECLARE_CF_TYPE_TRAIT (ClassName ) \
413
+ template <> \
414
+ struct WTF::CFTypeTrait<ClassName##Ref> { \
415
+ static inline CFTypeID typeID (void ) { return ClassName##GetTypeID (); } \
416
+ };
417
+
418
+ WTF_DECLARE_CF_TYPE_TRAIT (CFArray);
419
+ WTF_DECLARE_CF_TYPE_TRAIT (CFDictionary);
420
+
421
+ #define WTF_DECLARE_CF_MUTABLE_TYPE_TRAIT (ClassName, MutableClassName ) \
422
+ template <> \
423
+ struct WTF::CFTypeTrait<MutableClassName##Ref> { \
424
+ static inline CFTypeID typeID (void ) { return ClassName##GetTypeID (); } \
425
+ };
426
+
427
+ WTF_DECLARE_CF_MUTABLE_TYPE_TRAIT (CFArray, CFMutableArray);
428
+ WTF_DECLARE_CF_MUTABLE_TYPE_TRAIT (CFDictionary, CFMutableDictionary);
429
+
278
430
using WTF::RetainPtr;
279
431
using WTF::adoptNS;
280
432
using WTF::adoptCF;
281
433
using WTF::retainPtr;
282
434
using WTF::downcast;
283
435
using WTF::bridge_cast;
436
+ using WTF::bridge_id_cast;
437
+ using WTF::is_objc;
438
+ using WTF::checked_objc_cast;
439
+ using WTF::dynamic_objc_cast;
440
+ using WTF::checked_cf_cast;
441
+ using WTF::dynamic_cf_cast;
0 commit comments