Index: base/mac/foundation_util.h |
diff --git a/base/mac/foundation_util.h b/base/mac/foundation_util.h |
index ee23a17fb16e6c0c5c6856c6cd0ccbd9dd43c120..847a7f044ecd71d69beb276503c966f337b3464b 100644 |
--- a/base/mac/foundation_util.h |
+++ b/base/mac/foundation_util.h |
@@ -252,14 +252,15 @@ CF_TO_NS_CAST_DECL(CTFont, NSFont); |
namespace base { |
namespace mac { |
-// CFCast<>() and CFCastStrict<>() cast a basic CFTypeRef to a more |
-// specific CoreFoundation type. The compatibility of the passed |
-// object is found by comparing its opaque type against the |
-// requested type identifier. If the supplied object is not |
-// compatible with the requested return type, CFCast<>() returns |
-// NULL and CFCastStrict<>() will DCHECK. Providing a NULL pointer |
-// to either variant results in NULL being returned without |
-// triggering any DCHECK. |
+// CFCast<>(), CFCastStrict<>() and CFStaticCast<> cast a basic CFTypeRef to a |
+// more specific CoreFoundation type. The compatibility of the passed object is |
+// found by comparing its opaque type against the requested type identifier. If |
+// the supplied object is not compatible with the requested return type: |
+// - CFCast<>() returns null, similar to dynamic_cast<>; |
+// - CFCastStrict<>() will DCHECK or return null in Release; and |
+// - CFStaticCast<>() will DCHECK but always cast, similar to static_cast<>. |
+// Providing a null pointer to any variant results in null being returned |
+// without triggering any DCHECK. |
// |
// Example usage: |
// CFNumberRef some_number = base::mac::CFCast<CFNumberRef>( |
@@ -267,13 +268,20 @@ namespace mac { |
// |
// CFTypeRef hello = CFSTR("hello world"); |
// CFStringRef some_string = base::mac::CFCastStrict<CFStringRef>(hello); |
- |
template<typename T> |
T CFCast(const CFTypeRef& cf_val); |
template<typename T> |
T CFCastStrict(const CFTypeRef& cf_val); |
+template<typename T> |
+T CFStaticCast(const CFTypeRef& cf_val) { |
+ DCHECK(!cf_val || CFCast<T>(cf_val)); |
+ // Note: CFTypeRef is const void*, but CGColorRef and some others are non- |
+ // const. So this may also cast away a const qualifier. |
+ return (T)(cf_val); |
+} |
+ |
#define CF_CAST_DECL(TypeCF) \ |
template<> BASE_EXPORT TypeCF##Ref \ |
CFCast<TypeCF##Ref>(const CFTypeRef& cf_val);\ |
@@ -307,21 +315,24 @@ CF_CAST_DECL(SecTrustedApplication); |
#if defined(__OBJC__) |
-// ObjCCast<>() and ObjCCastStrict<>() cast a basic id to a more |
-// specific (NSObject-derived) type. The compatibility of the passed |
-// object is found by checking if it's a kind of the requested type |
-// identifier. If the supplied object is not compatible with the |
-// requested return type, ObjCCast<>() returns nil and |
-// ObjCCastStrict<>() will DCHECK. Providing a nil pointer to either |
-// variant results in nil being returned without triggering any DCHECK. |
+// ObjCCast<>(), ObjCCastStrict<>() and ObjCStaticCast cast a basic id to a more |
+// specific (NSObject-derived) type. The compatibility of the passed object is |
+// found by checking if it's a kind of the requested type identifier. If the |
+// supplied object is not compatible with the requested return type: |
+// - ObjCCast<>() returns nil, similar to dynamic_cast<>, |
+// - ObjCCastStrict<>() will DCHECK or return nil in Release; and |
+// - ObjCStaticCast<>() will DCHECK but always cast, similar to static_cast<>. |
+// Providing a nil pointer to any variant results in nil being returned without |
+// triggering any DCHECK. |
// |
-// The strict variant is useful when retrieving a value from a |
-// collection which only has values of a specific type, e.g. an |
-// NSArray of NSStrings. The non-strict variant is useful when |
-// retrieving values from data that you can't fully control. For |
-// example, a plist read from disk may be beyond your exclusive |
-// control, so you'd only want to check that the values you retrieve |
+// The strict variant is useful when retrieving a value from a collection which |
+// only has values of a specific type, e.g. an NSArray of NSStrings. The non- |
+// strict variant is useful when retrieving values from data that you can't |
+// fully control. For example, a plist read from disk may be beyond your |
+// exclusive control, so you'd only want to check that the values you retrieve |
// from it are of the expected types, but not crash if they're not. |
+// ObjCStaticCast should be preferred when you have a strong contract specifying |
+// the type and good test coverage. |
// |
// Example usage: |
// NSString* version = base::mac::ObjCCast<NSString>( |
@@ -344,6 +355,12 @@ T* ObjCCastStrict(id objc_val) { |
return rv; |
} |
+template<typename T> |
+T* ObjCStaticCast(id objc_val) { |
+ DCHECK(!objc_val || ObjCCast<T>(objc_val)); |
+ return reinterpret_cast<T*>(objc_val); |
+} |
+ |
#endif // defined(__OBJC__) |
// Helper function for GetValueFromDictionary to create the error message |