Skip to content

Instantly share code, notes, and snippets.

@pmj
Created July 9, 2012 10:34
Show Gist options
  • Save pmj/3075688 to your computer and use it in GitHub Desktop.
Save pmj/3075688 to your computer and use it in GitHub Desktop.
WIP NSDictionary typed destructuring bind.
// To be used something like this:
SSDC_BIND_DICTIONARY_TYPED(some_dictionary,
NSNumber, count, @"count_key",
NSArray, array_data, kSomeArrayKey,
NSString, a_string, stringkey);
/* this produces the variables count, array_data, and a_string, which
* have the specified static AND dynamic types (i.e. if objectForKey:stringKey
* is not actually an NSString, a_string will contain nil, not the object that
* will throw exceptions when used as a string.
*/
// here we go, macro definition time:
#define SSDC_CAST(TYPE, EXPR) \
({ \
__typeof(EXPR) _cast_expr_tmp = (EXPR); \
__typeof(EXPR) _super_check_ref __attribute__((unused)) = (TYPE*)nil; \
(TYPE*)SSDCCast(_cast_expr_tmp, [TYPE class]); \
})
#define SSDC_NUM_ARGS(...) SSDC_NUM_ARGS_IMPL(__VA_ARGS__, 30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1)
#define SSDC_NUM_ARGS_IMPL(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,N,...) N
#define SSDC_MACRO_DISPATCHER(MACRO, ...) SSDC_MACRO_DISPATCHER_(MACRO, SSDC_NUM_ARGS(__VA_ARGS__))
#define SSDC_MACRO_DISPATCHER_(MACRO, NARGS) SSDC_MACRO_DISPATCHER__(MACRO, NARGS)
#define SSDC_MACRO_DISPATCHER__(MACRO, NARGS) MACRO ## NARGS
#define SSDC_CONCAT(a, b) a ## b
#define SSDC_CONCAT2(a, b) SSDC_CONCAT(a, b)
#define SSDC_UNIQ(prefix) SSDC_CONCAT2(prefix, __LINE__)
#define SSDC_BIND_DICTIONARY_TYPED(DICT, ...) \
SSDC_MACRO_DISPATCHER(SSDC_BIND_DICTIONARY_VALUES_TYPED_, __VA_ARGS__)(DICT, __VA_ARGS__)
#define SSDC_BIND_DICTIONARY_VALUES_TYPED_3(DICT, TYPE1, VAR1, KEY1) \
TYPE1* VAR1 = SSDC_CAST(TYPE1, [(DICT) objectForKey:(KEY1)])
#define SSDC_BIND_DICTIONARY_VALUES_TYPED_6(DICT, TYPE1, VAR1, KEY1, TYPE2, VAR2, KEY2) \
NSDictionary* SSDC_UNIQ(_ssdc_temp_bind_dictionary_) = (DICT); \
TYPE1* VAR1 = SSDC_CAST(TYPE1, [SSDC_UNIQ(_ssdc_temp_bind_dictionary_) objectForKey:(KEY1)]); \
TYPE2* VAR2 = SSDC_CAST(TYPE2, [SSDC_UNIQ(_ssdc_temp_bind_dictionary_) objectForKey:(KEY2)])
#define SSDC_BIND_DICTIONARY_VALUES_TYPED_9(DICT, TYPE1, VAR1, KEY1, TYPE2, VAR2, KEY2, TYPE3, VAR3, KEY3) \
NSDictionary* SSDC_UNIQ(_ssdc_temp_bind_dictionary_) = (DICT); \
TYPE1* VAR1 = SSDC_CAST(TYPE1, [SSDC_UNIQ(_ssdc_temp_bind_dictionary_) objectForKey:(KEY1)]); \
TYPE2* VAR2 = SSDC_CAST(TYPE2, [SSDC_UNIQ(_ssdc_temp_bind_dictionary_) objectForKey:(KEY2)]); \
TYPE3* VAR3 = SSDC_CAST(TYPE3, [SSDC_UNIQ(_ssdc_temp_bind_dictionary_) objectForKey:(KEY3)])
#define SSDC_BIND_DICTIONARY_VALUES_TYPED_12(DICT, TYPE1, VAR1, KEY1, TYPE2, VAR2, KEY2, TYPE3, VAR3, KEY3, TYPE4, VAR4, KEY4) \
NSDictionary* SSDC_UNIQ(_ssdc_temp_bind_dictionary_) = (DICT); \
TYPE1* VAR1 = SSDC_CAST(TYPE1, [SSDC_UNIQ(_ssdc_temp_bind_dictionary_) objectForKey:(KEY1)]); \
TYPE2* VAR2 = SSDC_CAST(TYPE2, [SSDC_UNIQ(_ssdc_temp_bind_dictionary_) objectForKey:(KEY2)]); \
TYPE3* VAR3 = SSDC_CAST(TYPE3, [SSDC_UNIQ(_ssdc_temp_bind_dictionary_) objectForKey:(KEY3)]); \
TYPE4* VAR4 = SSDC_CAST(TYPE4, [SSDC_UNIQ(_ssdc_temp_bind_dictionary_) objectForKey:(KEY4)])
#define SSDC_BIND_DICTIONARY_VALUES_TYPED_15(DICT, TYPE1, VAR1, KEY1, TYPE2, VAR2, KEY2, TYPE3, VAR3, KEY3, TYPE4, VAR4, KEY4, TYPE5, VAR5, KEY5) \
NSDictionary* SSDC_UNIQ(_ssdc_temp_bind_dictionary_) = (DICT); \
TYPE1* VAR1 = SSDC_CAST(TYPE1, [SSDC_UNIQ(_ssdc_temp_bind_dictionary_) objectForKey:(KEY1)]); \
TYPE2* VAR2 = SSDC_CAST(TYPE2, [SSDC_UNIQ(_ssdc_temp_bind_dictionary_) objectForKey:(KEY2)]); \
TYPE3* VAR3 = SSDC_CAST(TYPE3, [SSDC_UNIQ(_ssdc_temp_bind_dictionary_) objectForKey:(KEY3)]); \
TYPE4* VAR4 = SSDC_CAST(TYPE4, [SSDC_UNIQ(_ssdc_temp_bind_dictionary_) objectForKey:(KEY4)]); \
TYPE5* VAR5 = SSDC_CAST(TYPE5, [SSDC_UNIQ(_ssdc_temp_bind_dictionary_) objectForKey:(KEY5)])
#define SSDC_BIND_DICTIONARY_VALUES_TYPED_24(DICT, TYPE1, VAR1, KEY1, TYPE2, VAR2, KEY2, TYPE3, VAR3, KEY3, TYPE4, VAR4, KEY4, TYPE5, VAR5, KEY5, TYPE6, VAR6, KEY6, TYPE7, VAR7, KEY7, TYPE8, VAR8, KEY8) \
NSDictionary* SSDC_UNIQ(_ssdc_temp_bind_dictionary_) = (DICT); \
TYPE1* VAR1 = SSDC_CAST(TYPE1, [SSDC_UNIQ(_ssdc_temp_bind_dictionary_) objectForKey:(KEY1)]); \
TYPE2* VAR2 = SSDC_CAST(TYPE2, [SSDC_UNIQ(_ssdc_temp_bind_dictionary_) objectForKey:(KEY2)]); \
TYPE3* VAR3 = SSDC_CAST(TYPE3, [SSDC_UNIQ(_ssdc_temp_bind_dictionary_) objectForKey:(KEY3)]); \
TYPE4* VAR4 = SSDC_CAST(TYPE4, [SSDC_UNIQ(_ssdc_temp_bind_dictionary_) objectForKey:(KEY4)]); \
TYPE5* VAR5 = SSDC_CAST(TYPE5, [SSDC_UNIQ(_ssdc_temp_bind_dictionary_) objectForKey:(KEY5)]); \
TYPE6* VAR6 = SSDC_CAST(TYPE6, [SSDC_UNIQ(_ssdc_temp_bind_dictionary_) objectForKey:(KEY6)]); \
TYPE7* VAR7 = SSDC_CAST(TYPE7, [SSDC_UNIQ(_ssdc_temp_bind_dictionary_) objectForKey:(KEY7)]); \
TYPE8* VAR8 = SSDC_CAST(TYPE8, [SSDC_UNIQ(_ssdc_temp_bind_dictionary_) objectForKey:(KEY8)])
#define SSDC_BIND_DICTIONARY_VALUES_TYPED_30(DICT, TYPE1, VAR1, KEY1, TYPE2, VAR2, KEY2, TYPE3, VAR3, KEY3, TYPE4, VAR4, KEY4, TYPE5, VAR5, KEY5, TYPE6, VAR6, KEY6, TYPE7, VAR7, KEY7, TYPE8, VAR8, KEY8, TYPE9, VAR9, KEY9, TYPE10, VAR10, KEY10) \
NSDictionary* SSDC_UNIQ(_ssdc_temp_bind_dictionary_) = (DICT); \
TYPE1* VAR1 = SSDC_CAST(TYPE1, [SSDC_UNIQ(_ssdc_temp_bind_dictionary_) objectForKey:(KEY1)]); \
TYPE2* VAR2 = SSDC_CAST(TYPE2, [SSDC_UNIQ(_ssdc_temp_bind_dictionary_) objectForKey:(KEY2)]); \
TYPE3* VAR3 = SSDC_CAST(TYPE3, [SSDC_UNIQ(_ssdc_temp_bind_dictionary_) objectForKey:(KEY3)]); \
TYPE4* VAR4 = SSDC_CAST(TYPE4, [SSDC_UNIQ(_ssdc_temp_bind_dictionary_) objectForKey:(KEY4)]); \
TYPE5* VAR5 = SSDC_CAST(TYPE5, [SSDC_UNIQ(_ssdc_temp_bind_dictionary_) objectForKey:(KEY5)]); \
TYPE6* VAR6 = SSDC_CAST(TYPE6, [SSDC_UNIQ(_ssdc_temp_bind_dictionary_) objectForKey:(KEY6)]); \
TYPE7* VAR7 = SSDC_CAST(TYPE7, [SSDC_UNIQ(_ssdc_temp_bind_dictionary_) objectForKey:(KEY7)]); \
TYPE8* VAR8 = SSDC_CAST(TYPE8, [SSDC_UNIQ(_ssdc_temp_bind_dictionary_) objectForKey:(KEY8)]); \
TYPE9* VAR9 = SSDC_CAST(TYPE9, [SSDC_UNIQ(_ssdc_temp_bind_dictionary_) objectForKey:(KEY9)]); \
TYPE10* VAR10 = SSDC_CAST(TYPE10, [SSDC_UNIQ(_ssdc_temp_bind_dictionary_) objectForKey:(KEY10)])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment