/*
 * This file is part of the YSSDWebImage package.
 * (c) Olivier Poitrey <rs@dailymotion.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

#import <Foundation/Foundation.h>
#import "YSSDmetamacros.h"

#ifndef YSSD_LOCK
#define YSSD_LOCK(lock) dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
#endif

#ifndef YSSD_UNLOCK
#define YSSD_UNLOCK(lock) dispatch_semaphore_signal(lock);
#endif

#ifndef YSSD_OPTIONS_CONTAINS
#define YSSD_OPTIONS_CONTAINS(options, value) (((options) & (value)) == (value))
#endif

#ifndef YSSD_CSTRING
#define YSSD_CSTRING(str) #str
#endif

#ifndef YSSD_NSSTRING
#define YSSD_NSSTRING(str) @(YSSD_CSTRING(str))
#endif

#ifndef YSSD_SEL_SPI
#define YSSD_SEL_SPI(name) NSSelectorFromString([NSString stringWithFormat:@"_%@", YSSD_NSSTRING(name)])
#endif

#ifndef weakify
#define weakify(...) \
yssd_keywordify \
metamacro_foreach_cxt(yssd_weakify_,, __weak, __VA_ARGS__)
#endif

#ifndef strongify
#define strongify(...) \
yssd_keywordify \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Wshadow\"") \
metamacro_foreach(yssd_strongify_,, __VA_ARGS__) \
_Pragma("clang diagnostic pop")
#endif

#define yssd_weakify_(INDEX, CONTEXT, VAR) \
CONTEXT __typeof__(VAR) metamacro_concat(VAR, _weak_) = (VAR);

#define yssd_strongify_(INDEX, VAR) \
__strong __typeof__(VAR) VAR = metamacro_concat(VAR, _weak_);

#if DEBUG
#define yssd_keywordify autoreleasepool {}
#else
#define yssd_keywordify try {} @catch (...) {}
#endif

#ifndef onExit
#define onExit \
yssd_keywordify \
__strong yssd_cleanupBlock_t metamacro_concat(yssd_exitBlock_, __LINE__) __attribute__((cleanup(yssd_executeCleanupBlock), unused)) = ^
#endif

typedef void (^yssd_cleanupBlock_t)(void);

#if defined(__cplusplus)
extern "C" {
#endif
    void yssd_executeCleanupBlock (__strong yssd_cleanupBlock_t *block);
#if defined(__cplusplus)
}
#endif
