Created
May 5, 2013 07:41
-
-
Save churchofthought/5520044 to your computer and use it in GitHub Desktop.
Non-coalescing OR macro for variable arguments and variable types including objects/primitives.
This file contains 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
#ifndef XIBXOR_OR | |
// | |
// XXOr.h | |
// | |
// Created by XibXor on 5/5/13. | |
// | |
// Non-coalescing OR macro for variable arguments and variable types including objects/primitives. | |
// Similar to || behavior in ECMAScript | |
// | |
// Usage: OR(a,b,...) | |
// | |
// Examples Below: | |
// NSLog(@"%@", OR(nil,@"", @{@"foo": @"bar"}, @[])); | |
// // outputs {foo = bar;} | |
// | |
// NSLog(@"%@", OR(nil,@"", @[], @"", [NSNull null])); | |
// // outputs <null> | |
// | |
// NSLog(@"%@", OR(nil,[NSNull null], @[], @"foo", @"", @"bar")); | |
// // outputs "foo" | |
// | |
// int x = 10; | |
// NSLog(@"%f", (float) OR(false, x, 5, 2)); | |
// // outputs 5.0 | |
// | |
// NSLog(@"%s", OR("", "foo", "bar")); | |
// // outputs bar | |
#define BOOST_PP_VARIADICS 1 | |
#include <boost/preprocessor/seq.hpp> | |
#include <boost/preprocessor/variadic/to_seq.hpp> | |
#define __OR(s, state, obj) (isEmpty(obj) ? state : obj) | |
#define _OR(seq) BOOST_PP_SEQ_FOLD_RIGHT(__OR, BOOST_PP_SEQ_ELEM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(seq)),seq), BOOST_PP_SEQ_POP_BACK(seq)) | |
#define OR(...) _OR(BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) | |
// define a slew of overloaded isEmpty functions for cases where we know the type at compile-time | |
// if the type cannot be deduced at compile time, the slower isEmpty(id) is used | |
// isEmpty(id) uses respondsToSelector which is extremely slow | |
// so cast your id types if you know them | |
// if you are passing arr[0], instead pass (NSString*)arr[0] | |
extern inline BOOL isEmpty(const char* s) { return !strlen(s); } | |
extern inline BOOL isEmpty(const long x) { return !x; } | |
extern inline BOOL isEmpty(const int x) { return !x; } | |
extern inline BOOL isEmpty(const short x) { return !x; } | |
extern inline BOOL isEmpty(const char x) { return !x; } | |
extern inline BOOL isEmpty(const double x) { return !x; } | |
extern inline BOOL isEmpty(const float x) { return !x; } | |
extern inline BOOL isEmpty(const NSString* o) { return !o.length; } | |
extern inline BOOL isEmpty(const NSData* o) { return !o.length; } | |
extern inline BOOL isEmpty(const NSArray* o) { return !o.count; } | |
extern inline BOOL isEmpty(const NSDictionary* o) { return !o.count; } | |
extern inline BOOL isEmpty(const NSNull* o) { return YES; } | |
extern inline BOOL isEmpty(const id o) { | |
return o == nil | |
|| o == [NSNull null] | |
|| ([o respondsToSelector:@selector(length)] | |
&& [o length] == 0) | |
|| ([o respondsToSelector:@selector(count)] | |
&& [o count] == 0); | |
} | |
#define XIBXOR_OR 1 | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment