-
-
Save loganmoseley/3373d094e9426af0febf168d31b7b83e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// CDZIdioms.h | |
// https://www.dzombak.com/blog/2015/02/Tiny-Swift-idioms-in-ObjC.html | |
// | |
// Created by Chris Dzombak on 3/21/15. | |
// Copyright (c) 2015 Chris Dzombak. All rights reserved. | |
// | |
#ifndef CDZIdioms_h | |
#define CDZIdioms_h | |
// assigns LHS = RHS iff RHS is non-nil and the right "kind" of class | |
#define if_let(CLASS, LHS, RHS) \ | |
for (id obj_ = as_option(RHS, CLASS); obj_ != nil;) \ | |
for (CLASS *const _Nonnull LHS = obj_; obj_ != nil; obj_ = nil) | |
// Treat this like a Swift guard: return from ELSE. | |
#define guard_let_else(CLASS, LHS, RHS, ELSE) \ | |
{ \ | |
let(CLASS) maybeRHS = as_option(RHS, CLASS); \ | |
for (BOOL cont = YES; cont; cont = NO) { \ | |
for (id ignoreMe = maybeRHS; cont && maybeRHS == nil; cont = NO) { \ | |
(void)ignoreMe; \ | |
ELSE \ | |
} \ | |
} \ | |
} \ | |
CLASS *const _Nonnull LHS = (CLASS *)(RHS); | |
#define as_checked(EXPR, KLASS) ({ id _obj = EXPR; NSCAssert([_obj isKindOfClass:[KLASS class]], @"Cannot cast %@ to %@", NSStringFromClass([_obj class]), NSStringFromClass([KLASS class])); _obj; }) | |
#define as_option(EXPR, KLASS) ({ id _obj = EXPR; if (![_obj isKindOfClass:[KLASS class]]) _obj = nil; _obj; }) | |
#define lazy_get(TYPE, NAME, VALUE) \ | |
@synthesize NAME = _##NAME; \ | |
- (TYPE)NAME { if (!_##NAME) _##NAME = (VALUE); return _##NAME; } | |
// FINAL added 2016-01-08; see: | |
// https://twitter.com/jesse_squires/status/664588682997964800 | |
// https://twitter.com/cdzombak/status/685475439804977152 | |
#define FINAL __attribute__((objc_subclassing_restricted)) | |
// let added 2016-02-24; see: | |
// https://twitter.com/smileyborg/status/702377742617190400 | |
#define let const | |
// nob_defer added 2016-01-09; see: http://nshipster.com/new-years-2016/ | |
// some helper declarations | |
#define _nob_macro_concat(a, b) a##b | |
#define nob_macro_concat(a, b) _nob_macro_concat(a, b) | |
typedef void(^nob_defer_block_t)(); | |
NS_INLINE void nob_deferFunc(__strong nob_defer_block_t *blockRef) | |
{ | |
nob_defer_block_t actualBlock = *blockRef; | |
actualBlock(); | |
} | |
// the core macro: | |
#define nob_defer(deferBlock) \ | |
__strong nob_defer_block_t nob_macro_concat(__nob_stack_defer_block_, __LINE__) __attribute__((cleanup(nob_deferFunc), unused)) = deferBlock | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment