Chromium Code Reviews| Index: base/mac/mac_util.h |
| diff --git a/base/mac/mac_util.h b/base/mac/mac_util.h |
| index d75fb6e792a8fca003b43b8572e4d20f744e5f1d..7f0a899e8fc4855bd127fdce0556870e31ad9354 100644 |
| --- a/base/mac/mac_util.h |
| +++ b/base/mac/mac_util.h |
| @@ -110,14 +110,22 @@ void RemoveFromLoginItems(); |
| // 'Login Item' with 'hide on startup' flag. Used to suppress opening windows. |
| bool WasLaunchedAsHiddenLoginItem(); |
| -#if defined(__OBJC__) |
| +} // namespace mac |
| +} // namespace base |
| -// Convert toll-free bridged CFTypes to NSTypes. This does not autorelease |
| -// |cf_val|. This is useful for the case where there is a CFType in a call that |
| -// expects an NSType and the compiler is complaining about const casting |
| -// problems. |
| -// The call is used like this: |
| +#if !defined(__OBJC__) |
| +#define OBJC_CPP_CLASS_DEFN(x) class x; |
| +#else // __OBJC__ |
| +#define OBJC_CPP_CLASS_DEFN(x) |
| +#endif // __OBJC__ |
| + |
| +// Convert toll-free bridged CFTypes to NSTypes and vice-versa. This does not |
| +// autorelease |cf_val|. This is useful for the case where there is a CFType in |
| +// a call that expects an NSType and the compiler is complaining about const |
| +// casting problems. |
| +// The calls are used like this: |
| // NSString *foo = CFToNSCast(CFSTR("Hello")); |
| +// CFStringRef foo2 = NSToCFCast(@"Hello"); |
| // The macro magic below is to enforce safe casting. It could possibly have |
| // been done using template function specialization, but template function |
| // specialization doesn't always work intuitively, |
| @@ -125,42 +133,72 @@ bool WasLaunchedAsHiddenLoginItem(); |
| // of macros and function overloading is used instead. |
| #define CF_TO_NS_CAST(TypeCF, TypeNS) \ |
| -inline TypeNS* CFToNSCast(TypeCF cf_val) { \ |
| +OBJC_CPP_CLASS_DEFN(TypeNS); \ |
| +\ |
| +namespace base { \ |
| +namespace mac { \ |
| +inline TypeNS* CFToNSCast(TypeCF##Ref cf_val) { \ |
| + DCHECK(!cf_val || TypeCF##GetTypeID() == CFGetTypeID(cf_val)); \ |
| TypeNS* ns_val = \ |
| const_cast<TypeNS*>(reinterpret_cast<const TypeNS*>(cf_val)); \ |
| - DCHECK(!ns_val || [ns_val isKindOfClass:[TypeNS class]]); \ |
| return ns_val; \ |
| -} |
| - |
| +} \ |
| +\ |
| +inline TypeCF##Ref NSToCFCast(TypeNS* ns_val) { \ |
| + TypeCF##Ref cf_val = reinterpret_cast<TypeCF##Ref>(ns_val); \ |
| + DCHECK(!cf_val || TypeCF##GetTypeID() == CFGetTypeID(cf_val)); \ |
| + return cf_val; \ |
| +} \ |
| +} \ |
| +} \ |
| + |
| +#define CF_TO_NS_MUTABLE_CAST(name) \ |
| +CF_TO_NS_CAST(CF##name, NS##name) \ |
| +OBJC_CPP_CLASS_DEFN(NSMutable##name) \ |
| +\ |
| +namespace base { \ |
| +namespace mac { \ |
| +inline NSMutable##name* CFToNSCast(CFMutable##name##Ref cf_val) { \ |
|
Nico
2011/03/02 02:21:22
I guess Elliot would be happier if all these funct
dmac
2011/03/02 22:20:09
Done.
|
| + DCHECK(!cf_val || CF##name##GetTypeID() == CFGetTypeID(cf_val)); \ |
| + NSMutable##name* ns_val = reinterpret_cast<NSMutable##name*>(cf_val); \ |
| + return ns_val; \ |
| +} \ |
| +\ |
| +inline CFMutable##name##Ref NSToCFCast(NSMutable##name* ns_val) { \ |
| + CFMutable##name##Ref cf_val = \ |
| + reinterpret_cast<CFMutable##name##Ref>(ns_val); \ |
| + DCHECK(!cf_val || CF##name##GetTypeID() == CFGetTypeID(cf_val)); \ |
| + return cf_val; \ |
| +} \ |
| +} \ |
| +} \ |
| // List of toll-free bridged types taken from: |
| // http://www.cocoadev.com/index.pl?TollFreeBridged |
| -CF_TO_NS_CAST(CFArrayRef, NSArray); |
| -CF_TO_NS_CAST(CFMutableArrayRef, NSMutableArray); |
| -CF_TO_NS_CAST(CFAttributedStringRef, NSAttributedString); |
| -CF_TO_NS_CAST(CFMutableAttributedStringRef, NSMutableAttributedString); |
| -CF_TO_NS_CAST(CFCalendarRef, NSCalendar); |
| -CF_TO_NS_CAST(CFCharacterSetRef, NSCharacterSet); |
| -CF_TO_NS_CAST(CFMutableCharacterSetRef, NSMutableCharacterSet); |
| -CF_TO_NS_CAST(CFDataRef, NSData); |
| -CF_TO_NS_CAST(CFMutableDataRef, NSMutableData); |
| -CF_TO_NS_CAST(CFDateRef, NSDate); |
| -CF_TO_NS_CAST(CFDictionaryRef, NSDictionary); |
| -CF_TO_NS_CAST(CFMutableDictionaryRef, NSMutableDictionary); |
| -CF_TO_NS_CAST(CFNumberRef, NSNumber); |
| -CF_TO_NS_CAST(CFRunLoopTimerRef, NSTimer); |
| -CF_TO_NS_CAST(CFSetRef, NSSet); |
| -CF_TO_NS_CAST(CFMutableSetRef, NSMutableSet); |
| -CF_TO_NS_CAST(CFStringRef, NSString); |
| -CF_TO_NS_CAST(CFMutableStringRef, NSMutableString); |
| -CF_TO_NS_CAST(CFURLRef, NSURL); |
| -CF_TO_NS_CAST(CFTimeZoneRef, NSTimeZone); |
| -CF_TO_NS_CAST(CFReadStreamRef, NSInputStream); |
| -CF_TO_NS_CAST(CFWriteStreamRef, NSOutputStream); |
| - |
| -#endif // __OBJC__ |
| - |
| -} // namespace mac |
| -} // namespace base |
| +CF_TO_NS_MUTABLE_CAST(Array); |
| +CF_TO_NS_MUTABLE_CAST(AttributedString); |
| +CF_TO_NS_CAST(CFCalendar, NSCalendar); |
| +CF_TO_NS_MUTABLE_CAST(CharacterSet); |
| +CF_TO_NS_MUTABLE_CAST(Data); |
| +CF_TO_NS_CAST(CFDate, NSDate); |
| +CF_TO_NS_MUTABLE_CAST(Dictionary); |
| +CF_TO_NS_CAST(CFError, NSError); |
| +CF_TO_NS_CAST(CFLocale, NSLocale); |
| +CF_TO_NS_CAST(CFNumber, NSNumber); |
| +CF_TO_NS_CAST(CFRunLoopTimer, NSTimer); |
| +CF_TO_NS_CAST(CFTimeZone, NSTimeZone); |
| +CF_TO_NS_MUTABLE_CAST(Set); |
| +CF_TO_NS_CAST(CFReadStream, NSInputStream); |
| +CF_TO_NS_CAST(CFWriteStream, NSOutputStream); |
| +CF_TO_NS_MUTABLE_CAST(String); |
| +CF_TO_NS_CAST(CFURL, NSURL); |
| + |
| +// Stream operations for CFTypes. They can be used with NSTypes as well |
| +// by using the NSToCFCast methods above. |
| +// e.g. LOG(INFO) << base::mac::NSToCFCast(@"foo"); |
| +// Operator << can not be overloaded for ObjectiveC types as the compiler |
| +// can not distinguish between overloads for id with overloads for void*. |
| +extern std::ostream& operator<<(std::ostream& o, const CFErrorRef err); |
| +extern std::ostream& operator<<(std::ostream& o, const CFStringRef str); |
| #endif // BASE_MAC_MAC_UTIL_H_ |