Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(768)

Unified Diff: base/mac/foundation_util.h

Issue 1927003004: Mac: Introduce "StaticCast" variants of base::mac::FooCastStrict, which do not typecheck in Release (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add StaticCast variants Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | ui/gfx/render_text_mac.mm » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
« no previous file with comments | « no previous file | ui/gfx/render_text_mac.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698