RenderCore/Utilities/CKInternalHelpers.mm (61 lines of code) (raw):

/* * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import "CKInternalHelpers.h" #import <objc/runtime.h> BOOL CKSubclassOverridesInstanceMethod(Class superclass, Class subclass, SEL selector) noexcept { if (![subclass isSubclassOfClass:superclass]) { return NO; } Method superclassMethod = class_getInstanceMethod(superclass, selector); Method subclassMethod = class_getInstanceMethod(subclass, selector); IMP superclassIMP = superclassMethod ? method_getImplementation(superclassMethod) : NULL; IMP subclassIMP = subclassMethod ? method_getImplementation(subclassMethod) : NULL; if (superclassIMP == NULL) { return NO; } return (superclassIMP != subclassIMP); } BOOL CKSubclassOverridesClassMethod(Class superclass, Class subclass, SEL selector) noexcept { if (![subclass isSubclassOfClass:superclass]) { return NO; } Method superclassMethod = class_getClassMethod(superclass, selector); Method subclassMethod = class_getClassMethod(subclass, selector); IMP superclassIMP = superclassMethod ? method_getImplementation(superclassMethod) : NULL; IMP subclassIMP = subclassMethod ? method_getImplementation(subclassMethod) : NULL; if (superclassIMP == NULL) { return NO; } return (superclassIMP != subclassIMP); } std::string CKStringFromPointer(const void *ptr) noexcept { char buf[64]; snprintf(buf, sizeof(buf), "%p", ptr); return buf; } CGFloat CKScreenScale() noexcept { static CGFloat _scale; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _scale = [UIScreen mainScreen].scale; }); return _scale; } CGFloat CKFloorPixelValue(CGFloat f) noexcept { return floor(f * CKScreenScale()) / CKScreenScale(); } CGFloat CKCeilPixelValue(CGFloat f) noexcept { return ceil(f * CKScreenScale()) / CKScreenScale(); } CGFloat CKRoundPixelValue(CGFloat f) noexcept { return round(f * CKScreenScale()) / CKScreenScale(); } auto CKReturnIfResponds(id const obj, SEL const sel) -> id { return [obj respondsToSelector:sel] ? obj : nil; }