20 #ifndef OBJFW_MACROS_H 21 #define OBJFW_MACROS_H 23 #include "objfw-defs.h" 25 #ifndef __STDC_LIMIT_MACROS 26 # define __STDC_LIMIT_MACROS 28 #ifndef __STDC_CONSTANT_MACROS 29 # define __STDC_CONSTANT_MACROS 44 #ifdef OF_OBJFW_RUNTIME 45 # ifdef OF_COMPILING_OBJFW 48 # include <ObjFWRT/ObjFWRT.h> 51 #ifdef OF_APPLE_RUNTIME 52 # include <objc/objc.h> 53 # include <objc/runtime.h> 54 # include <objc/message.h> 58 # define restrict __restrict__ 59 #elif __STDC_VERSION__ < 199901L 63 #if __STDC_VERSION__ >= 201112L && !defined(static_assert) 65 # define static_assert _Static_assert 68 #if defined(OF_HAVE__THREAD_LOCAL) 69 # define OF_HAVE_COMPILER_TLS 70 # ifdef OF_HAVE_THREADS_H 75 # define thread_local _Thread_local 78 # define thread_local _Thread_local 80 #elif defined(OF_HAVE___THREAD) 81 # define OF_HAVE_COMPILER_TLS 82 # define thread_local __thread 89 #if defined(OF_HAVE_COMPILER_TLS) && defined(OF_IOS) && defined(OF_X86) 90 # undef OF_HAVE_COMPILER_TLS 94 # define OF_INLINE inline __attribute__((__always_inline__)) 95 # define OF_LIKELY(cond) (__builtin_expect(!!(cond), 1)) 96 # define OF_UNLIKELY(cond) (__builtin_expect(!!(cond), 0)) 97 # define OF_CONST_FUNC __attribute__((__const__)) 98 # define OF_NO_RETURN_FUNC __attribute__((__noreturn__)) 99 # define OF_WEAK_REF(sym) __attribute__((__weakref__(sym))) 101 # define OF_INLINE inline 102 # define OF_LIKELY(cond) (cond) 103 # define OF_UNLIKELY(cond) (cond) 104 # define OF_CONST_FUNC 105 # define OF_NO_RETURN_FUNC 106 # define OF_WEAK_REF(sym) 109 #if __STDC_VERSION__ >= 201112L 110 # define OF_ALIGN(size) _Alignas(size) 111 # define OF_ALIGNOF(type) _Alignof(type) 112 # define OF_ALIGNAS(type) _Alignas(type) 114 # define OF_ALIGN(size) __attribute__((__aligned__(size))) 115 # define OF_ALIGNOF(type) __alignof__(type) 116 # define OF_ALIGNAS(type) OF_ALIGN(OF_ALIGNOF(type)) 119 #ifdef __BIGGEST_ALIGNMENT__ 120 # define OF_BIGGEST_ALIGNMENT __BIGGEST_ALIGNMENT__ 123 # define OF_BIGGEST_ALIGNMENT 16 129 #if (defined(OF_AMD64) || defined(OF_X86)) && OF_BIGGEST_ALIGNMENT < 16 130 # undef OF_BIGGEST_ALIGNMENT 131 # define OF_BIGGEST_ALIGNMENT 16 134 #define OF_PREPROCESSOR_CONCAT2(a, b) a##b 135 #define OF_PREPROCESSOR_CONCAT(a, b) OF_PREPROCESSOR_CONCAT2(a, b) 137 #if __OBJFW_RUNTIME_ABI__ || (defined(OF_APPLE_RUNTIME) && defined(__OBJC2__)) 138 # define OF_HAVE_NONFRAGILE_IVARS 141 #ifdef OF_HAVE_NONFRAGILE_IVARS 142 # define OF_RESERVE_IVARS(cls, num) 144 # define OF_RESERVE_IVARS(cls, num) \ 146 void *OF_PREPROCESSOR_CONCAT(_reserved_, cls)[num]; 150 # define OF_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) 152 # define OF_GCC_VERSION 0 155 #define OF_STRINGIFY(s) OF_STRINGIFY2(s) 156 #define OF_STRINGIFY2(s) #s 158 #ifndef __has_feature 159 # define __has_feature(x) 0 162 #ifndef __has_attribute 163 # define __has_attribute(x) 0 166 #if __has_feature(objc_bool) 168 # define YES __objc_yes 170 # define NO __objc_no 173 # define true ((bool)1) 175 # define false ((bool)0) 179 #if !__has_feature(objc_instancetype) 180 # define instancetype id 183 #if __has_feature(blocks) 184 # define OF_HAVE_BLOCKS 187 #if __has_feature(objc_arc) 188 # define OF_RETURNS_RETAINED __attribute__((__ns_returns_retained__)) 189 # define OF_RETURNS_NOT_RETAINED __attribute__((__ns_returns_not_retained__)) 190 # define OF_RETURNS_INNER_POINTER \ 191 __attribute__((__objc_returns_inner_pointer__)) 192 # define OF_CONSUMED __attribute__((__ns_consumed__)) 193 # define OF_WEAK_UNAVAILABLE __attribute__((__objc_arc_weak_unavailable__)) 195 # define OF_RETURNS_RETAINED 196 # define OF_RETURNS_NOT_RETAINED 197 # define OF_RETURNS_INNER_POINTER 199 # define OF_WEAK_UNAVAILABLE 204 # undef __unsafe_unretained 206 # undef __autoreleasing 207 # define __unsafe_unretained 209 # define __autoreleasing 212 #if __has_feature(objc_generics) 213 # define OF_HAVE_GENERICS 214 # define OF_GENERIC(...) <__VA_ARGS__> 216 # define OF_GENERIC(...) 219 #if __has_feature(nullability) 220 # define OF_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin") 221 # define OF_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end") 222 # define OF_NULLABLE_PROPERTY(...) (__VA_ARGS__, nullable) 223 # define OF_NULL_RESETTABLE_PROPERTY(...) (__VA_ARGS__, null_resettable) 225 # define OF_ASSUME_NONNULL_BEGIN 226 # define OF_ASSUME_NONNULL_END 229 # define _Null_unspecified 230 # define OF_NULLABLE_PROPERTY 231 # define OF_NULL_RESETTABLE_PROPERTY 234 # define null_unspecified 237 #if __has_feature(objc_kindof) 238 # define OF_KINDOF(class_) __kindof class_ 240 # define OF_KINDOF(class_) id 243 #if __has_feature(objc_class_property) 244 # define OF_HAVE_CLASS_PROPERTIES 247 #if defined(__clang__) || OF_GCC_VERSION >= 405 248 # define OF_UNREACHABLE __builtin_unreachable(); 250 # define OF_UNREACHABLE abort(); 253 #if defined(__clang__) || OF_GCC_VERSION >= 406 254 # define OF_SENTINEL __attribute__((__sentinel__)) 255 # define OF_NO_RETURN __attribute__((__noreturn__)) 258 # define OF_NO_RETURN 262 # define OF_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__)) 264 # define OF_WARN_UNUSED_RESULT 267 #if __has_attribute(__unavailable__) 268 # define OF_UNAVAILABLE __attribute__((__unavailable__)) 270 # define OF_UNAVAILABLE 273 #if __has_attribute(__objc_requires_super__) 274 # define OF_REQUIRES_SUPER __attribute__((__objc_requires_super__)) 276 # define OF_REQUIRES_SUPER 279 #if __has_attribute(__objc_root_class__) 280 # define OF_ROOT_CLASS __attribute__((__objc_root_class__)) 282 # define OF_ROOT_CLASS 285 #if __has_attribute(__objc_subclassing_restricted__) 286 # define OF_SUBCLASSING_RESTRICTED \ 287 __attribute__((__objc_subclassing_restricted__)) 289 # define OF_SUBCLASSING_RESTRICTED 292 #if __has_attribute(__objc_method_family__) 293 # define OF_METHOD_FAMILY(f) __attribute__((__objc_method_family__(f))) 295 # define OF_METHOD_FAMILY(f) 298 #if __has_attribute(__objc_designated_initializer__) 299 # define OF_DESIGNATED_INITIALIZER \ 300 __attribute__((__objc_designated_initializer__)) 302 # define OF_DESIGNATED_INITIALIZER 305 #if defined(__clang__) || OF_GCC_VERSION >= 405 306 # define OF_DEPRECATED(project, major, minor, msg) \ 307 __attribute__((__deprecated__("Deprecated in " #project " " \ 308 #major "." #minor ": " msg))) 309 #elif defined(__GNUC__) 310 # define OF_DEPRECATED(project, major, minor, msg) \ 311 __attribute__((__deprecated__)) 313 # define OF_DEPRECATED(project, major, minor, msg) 316 #if __has_attribute(__objc_boxable__) 317 # define OF_BOXABLE __attribute__((__objc_boxable__)) 322 #if __has_attribute(__swift_name__) 323 # define OF_SWIFT_NAME(name) __attribute__((__swift_name__(name))) 325 # define OF_SWIFT_NAME(name) 328 #if __has_attribute(__objc_direct__) && defined(OF_APPLE_RUNTIME) 329 # define OF_DIRECT __attribute__((__objc_direct__)) 333 #if __has_attribute(__objc_direct_members__) && defined(OF_APPLE_RUNTIME) 334 # define OF_DIRECT_MEMBERS __attribute__((__objc_direct_members__)) 336 # define OF_DIRECT_MEMBERS 339 #ifdef OF_APPLE_RUNTIME 340 # if defined(OF_AMD64) || defined(OF_X86) || defined(OF_ARM64) || \ 341 defined(OF_ARM) || defined(OF_POWERPC) 342 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR 343 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET 347 # if defined(OF_AMD64) || defined(OF_X86) || \ 348 defined(OF_ARM64) || defined(OF_ARM) || defined(OF_POWERPC) || \ 349 defined(OF_MIPS) || defined(OF_SPARC64) || defined(OF_SPARC) 350 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR 351 # if __OBJFW_RUNTIME_ABI__ >= 800 352 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET 355 # elif defined(OF_MACH_O) 356 # if defined(OF_AMD64) 357 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR 358 # if __OBJFW_RUNTIME_ABI__ >= 800 359 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET 362 # elif defined(OF_WINDOWS) 363 # if defined(OF_AMD64) || defined(OF_X86) 364 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR 365 # if __OBJFW_RUNTIME_ABI__ >= 800 366 # define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET 372 #define OFMaxRetainCount UINT_MAX 374 #ifdef OBJC_COMPILING_RUNTIME 375 # define OFEnsure(cond) \ 377 if OF_UNLIKELY (!(cond)) \ 378 objc_error("ObjFWRT @ " __FILE__ ":" \ 379 OF_STRINGIFY(__LINE__), \ 380 "Failed to ensure condition:\n" #cond); \ 391 # define OFEnsure(cond) \ 393 if OF_UNLIKELY (!(cond)) { \ 394 OFLog(@"Failed to ensure condition in " \ 395 @__FILE__ ":%d: " @#cond, __LINE__); \ 402 # define OFAssert(...) OFEnsure(__VA_ARGS__) 404 # define OFAssert(...) 407 #define OF_UNRECOGNIZED_SELECTOR OFMethodNotFound(self, _cmd); 408 #if __has_feature(objc_arc) 409 # define OF_INVALID_INIT_METHOD OFMethodNotFound(self, _cmd); 411 # define OF_INVALID_INIT_METHOD \ 413 OFMethodNotFound(self, _cmd); \ 422 # define OF_DEALLOC_UNSUPPORTED \ 423 [self doesNotRecognizeSelector: _cmd]; \ 427 _Pragma("clang diagnostic push"); \ 428 _Pragma("clang diagnostic ignored \"-Wunreachable-code\""); \ 430 _Pragma("clang diagnostic pop"); 432 # define OF_DEALLOC_UNSUPPORTED \ 433 [self doesNotRecognizeSelector: _cmd]; \ 439 #define OF_SINGLETON_METHODS \ 440 - (instancetype)autorelease \ 445 - (instancetype)retain \ 454 - (unsigned int)retainCount \ 456 return OFMaxRetainCount; \ 461 OF_DEALLOC_UNSUPPORTED \ 464 #define OF_CONSTRUCTOR(prio) \ 465 static void __attribute__((__constructor__(prio))) \ 466 OF_PREPROCESSOR_CONCAT(constructor, __LINE__)(void) 467 #define OF_DESTRUCTOR(prio) \ 468 static void __attribute__((__destructor__(prio))) \ 469 OF_PREPROCESSOR_CONCAT(destructor, __LINE__)(void) 471 static OF_INLINE uint16_t OF_CONST_FUNC
472 OFByteSwap16Const(uint16_t i)
474 return (i & UINT16_C(0xFF00)) >> 8 | (i & UINT16_C(0x00FF)) << 8;
477 static OF_INLINE uint32_t OF_CONST_FUNC
478 OFByteSwap32Const(uint32_t i)
480 return (i & UINT32_C(0xFF000000)) >> 24 |
481 (i & UINT32_C(0x00FF0000)) >> 8 |
482 (i & UINT32_C(0x0000FF00)) << 8 |
483 (i & UINT32_C(0x000000FF)) << 24;
486 static OF_INLINE uint64_t OF_CONST_FUNC
487 OFByteSwap64Const(uint64_t i)
489 return (i & UINT64_C(0xFF00000000000000)) >> 56 |
490 (i & UINT64_C(0x00FF000000000000)) >> 40 |
491 (i & UINT64_C(0x0000FF0000000000)) >> 24 |
492 (i & UINT64_C(0x000000FF00000000)) >> 8 |
493 (i & UINT64_C(0x00000000FF000000)) << 8 |
494 (i & UINT64_C(0x0000000000FF0000)) << 24 |
495 (i & UINT64_C(0x000000000000FF00)) << 40 |
496 (i & UINT64_C(0x00000000000000FF)) << 56;
499 static OF_INLINE uint16_t OF_CONST_FUNC
500 OFByteSwap16NonConst(uint16_t i)
502 #if defined(OF_HAVE_BUILTIN_BSWAP16) 503 return __builtin_bswap16(i);
504 #elif (defined(OF_AMD64) || defined(OF_X86)) && defined(__GNUC__) 506 "xchg{b} { %h0, %b0 | %b0, %h0 }" 510 #elif defined(OF_POWERPC) && defined(__GNUC__) 517 #elif defined(OF_ARMV6) && defined(__GNUC__) 524 i = (i & UINT16_C(0xFF00)) >> 8 |
525 (i & UINT16_C(0x00FF)) << 8;
530 static OF_INLINE uint32_t OF_CONST_FUNC
531 OFByteSwap32NonConst(uint32_t i)
533 #if defined(OF_HAVE_BUILTIN_BSWAP32) 534 return __builtin_bswap32(i);
535 #elif (defined(OF_AMD64) || defined(OF_X86)) && defined(__GNUC__) 541 #elif defined(OF_POWERPC) && defined(__GNUC__) 548 #elif defined(OF_ARMV6) && defined(__GNUC__) 555 i = (i & UINT32_C(0xFF000000)) >> 24 |
556 (i & UINT32_C(0x00FF0000)) >> 8 |
557 (i & UINT32_C(0x0000FF00)) << 8 |
558 (i & UINT32_C(0x000000FF)) << 24;
563 static OF_INLINE uint64_t OF_CONST_FUNC
564 OFByteSwap64NonConst(uint64_t i)
566 #if defined(OF_HAVE_BUILTIN_BSWAP64) 567 return __builtin_bswap64(i);
568 #elif defined(OF_AMD64) && defined(__GNUC__) 574 #elif defined(OF_X86) && defined(__GNUC__) 578 "xchg{l} { %%eax, %%edx | edx, eax }" 583 i = (uint64_t)OFByteSwap32NonConst(
584 (uint32_t)(i & UINT32_C(0xFFFFFFFF))) << 32 |
585 OFByteSwap32NonConst((uint32_t)(i >> 32));
591 # define OFByteSwap16(i) \ 592 (__builtin_constant_p(i) ? OFByteSwap16Const(i) : OFByteSwap16NonConst(i)) 593 # define OFByteSwap32(i) \ 594 (__builtin_constant_p(i) ? OFByteSwap32Const(i) : OFByteSwap32NonConst(i)) 595 # define OFByteSwap64(i) \ 596 (__builtin_constant_p(i) ? OFByteSwap64Const(i) : OFByteSwap64NonConst(i)) 598 # define OFByteSwap16(i) OFByteSwap16Const(i) 599 # define OFByteSwap32(i) OFByteSwap32Const(i) 600 # define OFByteSwap64(i) OFByteSwap64Const(i) 603 static OF_INLINE uint32_t
604 OFFloatToRawUInt32(
float f)
611 static OF_INLINE
float 612 OFRawUInt32ToFloat(uint32_t uInt32)
615 memcpy(&ret, &uInt32, 4);
619 static OF_INLINE uint64_t
620 OFDoubleToRawUInt64(
double d)
627 static OF_INLINE
double 628 OFRawUInt64ToDouble(uint64_t uInt64)
631 memcpy(&ret, &uInt64, 8);
635 static OF_INLINE
float OF_CONST_FUNC
636 OFByteSwapFloat(
float f)
638 return OFRawUInt32ToFloat(OFByteSwap32(OFFloatToRawUInt32(f)));
641 static OF_INLINE
double OF_CONST_FUNC
642 OFByteSwapDouble(
double d)
644 return OFRawUInt64ToDouble(OFByteSwap64(OFDoubleToRawUInt64(d)));
648 # define OFFromBigEndian16(i) (i) 649 # define OFFromBigEndian32(i) (i) 650 # define OFFromBigEndian64(i) (i) 651 # define OFFromLittleEndian16(i) OFByteSwap16(i) 652 # define OFFromLittleEndian32(i) OFByteSwap32(i) 653 # define OFFromLittleEndian64(i) OFByteSwap64(i) 654 # define OFToBigEndian16(i) (i) 655 # define OFToBigEndian32(i) (i) 656 # define OFToBigEndian64(i) (i) 657 # define OFToLittleEndian16(i) OFByteSwap16(i) 658 # define OFToLittleEndian32(i) OFByteSwap32(i) 659 # define OFToLittleEndian64(i) OFByteSwap64(i) 661 # define OFFromBigEndian16(i) OFByteSwap16(i) 662 # define OFFromBigEndian32(i) OFByteSwap32(i) 663 # define OFFromBigEndian64(i) OFByteSwap64(i) 664 # define OFFromLittleEndian16(i) (i) 665 # define OFFromLittleEndian32(i) (i) 666 # define OFFromLittleEndian64(i) (i) 667 # define OFToBigEndian16(i) OFByteSwap16(i) 668 # define OFToBigEndian32(i) OFByteSwap32(i) 669 # define OFToBigEndian64(i) OFByteSwap64(i) 670 # define OFToLittleEndian16(i) (i) 671 # define OFToLittleEndian32(i) (i) 672 # define OFToLittleEndian64(i) (i) 675 #ifdef OF_FLOAT_BIG_ENDIAN 676 # define OFFromBigEndianFloat(f) (f) 677 # define OFFromBigEndianDouble(d) (d) 678 # define OFFromLittleEndianFloat(f) OFByteSwapFloat(f) 679 # define OFFromLittleEndianDouble(d) OFByteSwapDouble(d) 680 # define OFToBigEndianFloat(f) (f) 681 # define OFToBigEndianDouble(d) (d) 682 # define OFToLittleEndianFloat(f) OFByteSwapFloat(f) 683 # define OFToLittleEndianDouble(d) OFByteSwapDouble(d) 685 # define OFFromBigEndianFloat(f) OFByteSwapFloat(f) 686 # define OFFromBigEndianDouble(d) OFByteSwapDouble(d) 687 # define OFFromLittleEndianFloat(f) (f) 688 # define OFFromLittleEndianDouble(d) (d) 689 # define OFToBigEndianFloat(f) OFByteSwapFloat(f) 690 # define OFToBigEndianDouble(d) OFByteSwapDouble(d) 691 # define OFToLittleEndianFloat(f) (f) 692 # define OFToLittleEndianDouble(d) (d) 695 #define OFRotateLeft(value, bits) \ 696 (((bits) % (sizeof(value) * 8)) > 0 \ 697 ? ((value) << ((bits) % (sizeof(value) * 8))) | \ 698 ((value) >> (sizeof(value) * 8 - ((bits) % (sizeof(value) * 8)))) \ 700 #define OFRotateRight(value, bits) \ 701 (((bits) % (sizeof(value) * 8)) > 0 \ 702 ? ((value) >> ((bits) % (sizeof(value) * 8))) | \ 703 ((value) << (sizeof(value) * 8 - ((bits) % (sizeof(value) * 8)))) \ 706 #define OFRoundUpToPowerOf2(pow2, value) \ 707 (((value) + (pow2) - 1) & ~((pow2) - 1)) 709 static OF_INLINE
bool 710 OFBitsetIsSet(
unsigned char *_Nonnull storage,
size_t idx)
712 return storage[idx / CHAR_BIT] & (1u << (idx % CHAR_BIT));
715 static OF_INLINE
void 716 OFBitsetSet(
unsigned char *_Nonnull storage,
size_t idx)
718 storage[idx / CHAR_BIT] |= (1u << (idx % CHAR_BIT));
721 static OF_INLINE
void 722 OFBitsetClear(
unsigned char *_Nonnull storage,
size_t idx)
724 storage[idx / CHAR_BIT] &= ~(1u << (idx % CHAR_BIT));
727 static OF_INLINE
void 728 OFZeroMemory(
void *_Nonnull buffer_,
size_t length)
730 volatile unsigned char *buffer = (
volatile unsigned char *)buffer_;
732 while (buffer < (
unsigned char *)buffer_ + length)
736 static OF_INLINE
bool 737 OFASCIIIsAlpha(
char c)
739 return ((c >=
'a' && c <=
'z') || (c >=
'A' && c <=
'Z'));
742 static OF_INLINE
bool 743 OFASCIIIsDigit(
char c)
745 return (c >=
'0' && c <=
'9');
748 static OF_INLINE
bool 749 OFASCIIIsAlnum(
char c)
751 return (OFASCIIIsAlpha(c) || OFASCIIIsDigit(c));
754 static OF_INLINE
bool 755 OFASCIIIsSpace(
char c)
757 return (c ==
' ' || c ==
'\t' || c ==
'\n' || c ==
'\r' || c ==
'\f' ||
761 static OF_INLINE
char 762 OFASCIIToUpper(
char c)
764 return (c >=
'a' && c <=
'z' ?
'A' + (c -
'a') : c);
767 static OF_INLINE
char 768 OFASCIIToLower(
char c)
770 return (c >=
'A' && c <=
'Z' ?
'a' + (c -
'A') : c);
A class for storing constant strings using the @"" literal.
Definition: OFConstantString.h:41
void OFLog(OFConstantString *format,...)
Logs the specified printf-style format to OFStdErr.
Definition: OFStdIOStream.m:94