ObjFW
Loading...
Searching...
No Matches
macros.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2008-2026 Jonathan Schleifer <js@nil.im>
3 *
4 * All rights reserved.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License version 3.0 only,
8 * as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
13 * version 3.0 for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * version 3.0 along with this program. If not, see
17 * <https://www.gnu.org/licenses/>.
18 */
19
20#ifndef OBJFW_MACROS_H
21#define OBJFW_MACROS_H
22
23#include "objfw-defs.h"
24
25#ifndef __STDC_LIMIT_MACROS
26# define __STDC_LIMIT_MACROS
27#endif
28#ifndef __STDC_CONSTANT_MACROS
29# define __STDC_CONSTANT_MACROS
30#endif
31
32#include <limits.h>
33#include <stdbool.h>
34#include <stddef.h>
35#include <stdint.h>
36#include <stdio.h>
37#include <stdlib.h>
38#include <string.h>
39
40#include <sys/time.h>
41
43
44#include "platform.h"
45
46#ifdef OF_OBJFW_RUNTIME
47# ifdef OF_COMPILING_OBJFW
48# include "ObjFWRT.h"
49# else
50# include <ObjFWRT/ObjFWRT.h>
51# endif
52#endif
53#ifdef OF_APPLE_RUNTIME
54# include <objc/objc.h>
55# include <objc/runtime.h>
56# include <objc/message.h>
57#endif
58
59#if defined(__GNUC__)
60# define restrict __restrict__
61#elif __STDC_VERSION__ < 199901L
62# define restrict
63#endif
64
65#if __STDC_VERSION__ >= 201112L && !defined(static_assert)
66/* C11 compiler, but old libc */
67# define static_assert _Static_assert
68#endif
69
70#if defined(OF_HAVE__THREAD_LOCAL)
71# define OF_HAVE_COMPILER_TLS
72# ifdef OF_HAVE_THREADS_H
73# include <threads.h>
74# ifdef OF_AIX
75/* AIX has a bug where thread_local is defined to "Thread_local;". */
76# undef thread_local
77# define thread_local _Thread_local
78# endif
79# else
80# define thread_local _Thread_local
81# endif
82#elif defined(OF_HAVE___THREAD)
83# define OF_HAVE_COMPILER_TLS
84# define thread_local __thread
85#endif
86
87/*
88 * Do not use compiler TLS when targeting the iOS simulator, as the iOS 9
89 * simulator does not support it (fails at runtime).
90 */
91#if defined(OF_HAVE_COMPILER_TLS) && defined(OF_IOS) && defined(OF_X86)
92# undef OF_HAVE_COMPILER_TLS
93#endif
94
95#ifdef __GNUC__
96# define OF_INLINE inline __attribute__((__always_inline__))
97# define OF_LIKELY(cond) (__builtin_expect(!!(cond), 1))
98# define OF_UNLIKELY(cond) (__builtin_expect(!!(cond), 0))
99# define OF_CONST_FUNC __attribute__((__const__))
100# define OF_NO_RETURN_FUNC __attribute__((__noreturn__))
101# define OF_WEAK_REF(sym) __attribute__((__weakref__(sym)))
102# if defined(OF_ELF) || defined(OF_MACHO)
103# define OF_VISIBILITY_HIDDEN __attribute__((__visibility__("hidden")))
104# define OF_VISIBILITY_INTERNAL __attribute__((__visibility__("internal")))
105# else
106# define OF_VISIBILITY_HIDDEN
107# define OF_VISIBILITY_INTERNAL
108# endif
109# define OF_MALLOC_FUNC __attribute__((__malloc__))
110#else
111# define OF_INLINE inline
112# define OF_LIKELY(cond) (cond)
113# define OF_UNLIKELY(cond) (cond)
114# define OF_CONST_FUNC
115# define OF_NO_RETURN_FUNC
116# define OF_WEAK_REF(sym)
117# define OF_VISIBILITY_HIDDEN
118# define OF_VISIBILITY_INTERNAL
119# define OF_MALLOC_FUNC
120#endif
121
122#if __STDC_VERSION__ >= 201112L
123# define OF_ALIGN(size) _Alignas(size)
124# define OF_ALIGNOF(type) _Alignof(type)
125# define OF_ALIGNAS(type) _Alignas(type)
126#else
127# define OF_ALIGN(size) __attribute__((__aligned__(size)))
128# define OF_ALIGNOF(type) __alignof__(type)
129# define OF_ALIGNAS(type) OF_ALIGN(OF_ALIGNOF(type))
130#endif
131
132#ifdef __BIGGEST_ALIGNMENT__
133# define OF_BIGGEST_ALIGNMENT __BIGGEST_ALIGNMENT__
134#else
135/* Hopefully no arch needs more than 16 byte alignment */
136# define OF_BIGGEST_ALIGNMENT 16
137#endif
138/*
139 * We use SSE inline assembly on AMD64 and x86, so it must never be smaller
140 * than 16.
141 */
142#if (defined(OF_AMD64) || defined(OF_X86)) && OF_BIGGEST_ALIGNMENT < 16
143# undef OF_BIGGEST_ALIGNMENT
144# define OF_BIGGEST_ALIGNMENT 16
145#endif
146
147#define OF_PREPROCESSOR_CONCAT2(a, b) a##b
148#define OF_PREPROCESSOR_CONCAT(a, b) OF_PREPROCESSOR_CONCAT2(a, b)
149#define OF_PREPROCESSOR_STRINGIFY2(x) #x
150#define OF_PREPROCESSOR_STRINGIFY(x) OF_PREPROCESSOR_STRINGIFY2(x)
151
152#if __OBJFW_RUNTIME_ABI__ || (defined(OF_APPLE_RUNTIME) && defined(__OBJC2__))
153# define OF_HAVE_NONFRAGILE_IVARS
154#endif
155
156#ifdef OF_HAVE_NONFRAGILE_IVARS
157# define OF_RESERVE_IVARS(cls, num)
158#else
159# define OF_RESERVE_IVARS(cls, num) \
160 @private \
161 void *OF_PREPROCESSOR_CONCAT(_reserved_, cls)[num];
162#endif
163
164#ifdef __GNUC__
165# define OF_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
166#else
167# define OF_GCC_VERSION 0
168#endif
169
170#define OF_STRINGIFY(s) OF_STRINGIFY2(s)
171#define OF_STRINGIFY2(s) #s
172
173#ifndef __has_feature
174# define __has_feature(x) 0
175#endif
176
177#ifndef __has_attribute
178# define __has_attribute(x) 0
179#endif
180
181#if __has_feature(objc_bool)
182# undef YES
183# define YES __objc_yes
184# undef NO
185# define NO __objc_no
186# ifndef __cplusplus
187# undef true
188# define true ((bool)1)
189# undef false
190# define false ((bool)0)
191# endif
192#endif
193
194#if !__has_feature(objc_instancetype)
195# define instancetype id
196#endif
197
198#if __has_feature(blocks)
199# define OF_HAVE_BLOCKS
200#endif
201
202#if __has_feature(objc_arc)
203# define OF_RETURNS_RETAINED __attribute__((__ns_returns_retained__))
204# define OF_RETURNS_NOT_RETAINED __attribute__((__ns_returns_not_retained__))
205# define OF_RETURNS_INNER_POINTER \
206 __attribute__((__objc_returns_inner_pointer__))
207# define OF_CONSUMED __attribute__((__ns_consumed__))
208# define OF_WEAK_UNAVAILABLE __attribute__((__objc_arc_weak_unavailable__))
209#else
210# define OF_RETURNS_RETAINED
211# define OF_RETURNS_NOT_RETAINED
212# define OF_RETURNS_INNER_POINTER
213# define OF_CONSUMED
214# define OF_WEAK_UNAVAILABLE
215/*
216 * undef them first, as new Clang versions have these as built-in defines even
217 * when ARC is disabled.
218 */
219# undef __unsafe_unretained
220# undef __bridge
221# undef __autoreleasing
222# define __unsafe_unretained
223# define __bridge
224# define __autoreleasing
225#endif
226
227#if __has_feature(objc_generics)
228# define OF_HAVE_GENERICS
229# define OF_GENERIC(...) <__VA_ARGS__>
230#else
231# define OF_GENERIC(...)
232#endif
233
234#if __has_feature(nullability)
235# define OF_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin")
236# define OF_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end")
237# define OF_NULLABLE_PROPERTY(...) (__VA_ARGS__, nullable)
238# define OF_NULL_RESETTABLE_PROPERTY(...) (__VA_ARGS__, null_resettable)
239#else
240# define OF_ASSUME_NONNULL_BEGIN
241# define OF_ASSUME_NONNULL_END
242# define _Nonnull
243# define _Nullable
244# define _Null_unspecified
245# define OF_NULLABLE_PROPERTY
246# define OF_NULL_RESETTABLE_PROPERTY
247# define nonnull
248# define nullable
249# define null_unspecified
250#endif
251
252#if __has_feature(objc_kindof)
253# define OF_KINDOF(class_) __kindof class_
254#else
255# define OF_KINDOF(class_) id
256#endif
257
258#if __has_feature(objc_class_property)
259# define OF_HAVE_CLASS_PROPERTIES
260#endif
261
262#if defined(__clang__) || OF_GCC_VERSION >= 405
263# define OF_UNREACHABLE __builtin_unreachable();
264#else
265# define OF_UNREACHABLE abort();
266#endif
267
268#if defined(__clang__) || OF_GCC_VERSION >= 406
269# define OF_SENTINEL __attribute__((__sentinel__))
270# define OF_NO_RETURN __attribute__((__noreturn__))
271#else
272# define OF_SENTINEL
273# define OF_NO_RETURN
274#endif
275
276#ifdef __clang__
277# define OF_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
278#else
279# define OF_WARN_UNUSED_RESULT
280#endif
281
282#if __has_attribute(__unavailable__)
283# define OF_UNAVAILABLE __attribute__((__unavailable__))
284#else
285# define OF_UNAVAILABLE
286#endif
287
288#if __has_attribute(__objc_requires_super__)
289# define OF_REQUIRES_SUPER __attribute__((__objc_requires_super__))
290#else
291# define OF_REQUIRES_SUPER
292#endif
293
294#if __has_attribute(__objc_root_class__)
295# define OF_ROOT_CLASS __attribute__((__objc_root_class__))
296#else
297# define OF_ROOT_CLASS
298#endif
299
300#if __has_attribute(__objc_subclassing_restricted__)
301# define OF_SUBCLASSING_RESTRICTED \
302 __attribute__((__objc_subclassing_restricted__))
303#else
304# define OF_SUBCLASSING_RESTRICTED
305#endif
306
307#if __has_attribute(__objc_method_family__)
308# define OF_METHOD_FAMILY(f) __attribute__((__objc_method_family__(f)))
309#else
310# define OF_METHOD_FAMILY(f)
311#endif
312
313#if __has_attribute(__objc_designated_initializer__)
314# define OF_DESIGNATED_INITIALIZER \
315 __attribute__((__objc_designated_initializer__))
316#else
317# define OF_DESIGNATED_INITIALIZER
318#endif
319
320#if defined(__clang__) || OF_GCC_VERSION >= 405
321# define OF_DEPRECATED(project, major, minor, msg) \
322 __attribute__((__deprecated__("Deprecated in " #project " " \
323 #major "." #minor ": " msg)))
324#elif defined(__GNUC__)
325# define OF_DEPRECATED(project, major, minor, msg) \
326 __attribute__((__deprecated__))
327#else
328# define OF_DEPRECATED(project, major, minor, msg)
329#endif
330
331#if __has_attribute(__objc_boxable__)
332# define OF_BOXABLE __attribute__((__objc_boxable__))
333#else
334# define OF_BOXABLE
335#endif
336
337#if __has_attribute(__swift_name__)
338# define OF_SWIFT_NAME(name) __attribute__((__swift_name__(name)))
339#else
340# define OF_SWIFT_NAME(name)
341#endif
342
343#if defined(OF_APPLE_RUNTIME) || (defined(OF_OBJFW_RUNTIME) && \
344 defined(__clang_major__) && __clang_major__ >= 21)
345# if __has_attribute(__objc_direct__)
346# define OF_DIRECT __attribute__((__objc_direct__))
347# define OF_DIRECT_PROPERTY(...) (__VA_ARGS__, direct)
348# endif
349# if __has_attribute(__objc_direct_members__)
350# define OF_DIRECT_MEMBERS __attribute__((__objc_direct_members__))
351# endif
352#endif
353#ifndef OF_DIRECT
354# define OF_DIRECT
355#endif
356#ifndef OF_DIRECT_PROPERTY
357# define OF_DIRECT_PROPERTY
358#endif
359#ifndef OF_DIRECT_MEMBERS
360# define OF_DIRECT_MEMBERS
361#endif
362
363#ifdef OF_APPLE_RUNTIME
364# if defined(OF_AMD64) || defined(OF_X86) || defined(OF_ARM64) || \
365 defined(OF_ARM) || defined(OF_POWERPC)
366# define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR
367# define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET
368# endif
369#else
370# if defined(OF_ELF)
371# if defined(OF_AMD64) || defined(OF_X86) || \
372 defined(OF_ARM64) || defined(OF_ARM) || \
373 defined(OF_POWERPC) || defined(OF_POWERPC64) || \
374 defined(OF_MIPS64_N64) || defined(OF_MIPS) || \
375 defined(OF_SPARC64) || defined(OF_SPARC) || \
376 defined(OF_RISCV64) || defined(OF_LOONGARCH64)
377# define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR
378# if __OBJFW_RUNTIME_ABI__ >= 800
379# define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET
380# endif
381# endif
382# elif defined(OF_MACH_O)
383# if defined(OF_AMD64)
384# define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR
385# if __OBJFW_RUNTIME_ABI__ >= 800
386# define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET
387# endif
388# endif
389# elif defined(OF_WINDOWS)
390# if defined(OF_AMD64) || defined(OF_X86) || defined(OF_ARM64)
391# define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR
392# if __OBJFW_RUNTIME_ABI__ >= 800
393# define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET
394# endif
395# endif
396# endif
397#endif
398
399#define OFMaxRetainCount UINT_MAX
400
401#ifdef OBJC_COMPILING_RUNTIME
402# define OFEnsure(cond) \
403 do { \
404 if OF_UNLIKELY (!(cond)) \
405 objc_error("ObjFWRT @ " __FILE__ ":" \
406 OF_STRINGIFY(__LINE__), \
407 "Failed to ensure condition:\n" #cond); \
408 } while(0)
409#else
410@class OFConstantString;
411# ifdef __cplusplus
412extern "C" {
413# endif
414extern void OFLog(OFConstantString *_Nonnull, ...);
415# ifdef __cplusplus
416}
417# endif
418# define OFEnsure(cond) \
419 do { \
420 if OF_UNLIKELY (!(cond)) { \
421 OFLog(@"Failed to ensure condition in " \
422 @__FILE__ ":%d: " @#cond, __LINE__); \
423 abort(); \
424 } \
425 } while (0)
426#endif
427
428#ifndef NDEBUG
429# define OFAssert(...) OFEnsure(__VA_ARGS__)
430#else
431# define OFAssert(...)
432#endif
433
434#define OF_UNRECOGNIZED_SELECTOR OFMethodNotFound(self, _cmd);
435#if __has_feature(objc_arc)
436# define OF_INVALID_INIT_METHOD OFMethodNotFound(self, _cmd);
437#else
438# define OF_INVALID_INIT_METHOD \
439 @try { \
440 OFMethodNotFound(self, _cmd); \
441 } @catch (id e) { \
442 objc_release(self); \
443 @throw e; \
444 } \
445 \
446 abort();
447#endif
448#ifdef __clang__
449# define OF_DEALLOC_UNSUPPORTED \
450 [self doesNotRecognizeSelector: _cmd]; \
451 \
452 abort(); \
453 \
454 _Pragma("clang diagnostic push"); \
455 _Pragma("clang diagnostic ignored \"-Wunreachable-code\""); \
456 [super dealloc]; /* Get rid of a stupid warning */ \
457 _Pragma("clang diagnostic pop");
458#else
459# define OF_DEALLOC_UNSUPPORTED \
460 [self doesNotRecognizeSelector: _cmd]; \
461 \
462 abort(); \
463 \
464 [super dealloc]; /* Get rid of a stupid warning */
465#endif
466#define OF_SINGLETON_METHODS \
467 - (instancetype)autorelease \
468 { \
469 return self; \
470 } \
471 \
472 - (instancetype)retain \
473 { \
474 return self; \
475 } \
476 \
477 - (void)release \
478 { \
479 } \
480 \
481 - (unsigned int)retainCount \
482 { \
483 return OFMaxRetainCount; \
484 } \
485 \
486 - (void)dealloc \
487 { \
488 OF_DEALLOC_UNSUPPORTED \
489 }
490
491#define OF_CONSTRUCTOR(prio) \
492 static void __attribute__((__constructor__(prio))) \
493 OF_PREPROCESSOR_CONCAT(constructor, __LINE__)(void)
494#define OF_DESTRUCTOR(prio) \
495 static void __attribute__((__destructor__(prio))) \
496 OF_PREPROCESSOR_CONCAT(destructor, __LINE__)(void)
497
498#define _OFByteSwap16Const(i) \
499 (((i) & UINT16_C(0xFF00)) >> 8 | ((i) & UINT16_C(0x00FF)) << 8)
500#define _OFByteSwap32Const(i) \
501 (((i) & UINT32_C(0xFF000000)) >> 24 | \
502 ((i) & UINT32_C(0x00FF0000)) >> 8 | \
503 ((i) & UINT32_C(0x0000FF00)) << 8 | \
504 ((i) & UINT32_C(0x000000FF)) << 24)
505#define _OFByteSwap64Const(i) \
506 (((i) & UINT64_C(0xFF00000000000000)) >> 56 | \
507 ((i) & UINT64_C(0x00FF000000000000)) >> 40 | \
508 ((i) & UINT64_C(0x0000FF0000000000)) >> 24 | \
509 ((i) & UINT64_C(0x000000FF00000000)) >> 8 | \
510 ((i) & UINT64_C(0x00000000FF000000)) << 8 | \
511 ((i) & UINT64_C(0x0000000000FF0000)) << 24 | \
512 ((i) & UINT64_C(0x000000000000FF00)) << 40 | \
513 ((i) & UINT64_C(0x00000000000000FF)) << 56)
514
515static OF_INLINE uint16_t OF_CONST_FUNC
516_OFByteSwap16NonConst(uint16_t i)
517{
518#if defined(OF_HAVE_BUILTIN_BSWAP16)
519 return __builtin_bswap16(i);
520#elif (defined(OF_AMD64) || defined(OF_X86)) && defined(__GNUC__)
521 __asm__ (
522 "xchg{b} { %h0, %b0 | %b0, %h0 }"
523 : "=Q" (i)
524 : "0" (i)
525 );
526#elif defined(OF_POWERPC) && defined(__GNUC__)
527 __asm__ (
528 "lhbrx %0, 0, %1"
529 : "=r" (i)
530 : "r" (&i),
531 "m" (i)
532 );
533#elif defined(OF_ARMV6) && defined(__GNUC__)
534 __asm__ (
535 "rev16 %0, %0"
536 : "=r" (i)
537 : "0" (i)
538 );
539#else
540 i = (i & UINT16_C(0xFF00)) >> 8 |
541 (i & UINT16_C(0x00FF)) << 8;
542#endif
543 return i;
544}
545
546static OF_INLINE uint32_t OF_CONST_FUNC
547_OFByteSwap32NonConst(uint32_t i)
548{
549#if defined(OF_HAVE_BUILTIN_BSWAP32)
550 return __builtin_bswap32(i);
551#elif (defined(OF_AMD64) || defined(OF_X86)) && defined(__GNUC__)
552 __asm__ (
553 "bswap %0"
554 : "=q" (i)
555 : "0" (i)
556 );
557#elif defined(OF_POWERPC) && defined(__GNUC__)
558 __asm__ (
559 "lwbrx %0, 0, %1"
560 : "=r" (i)
561 : "r" (&i),
562 "m" (i)
563 );
564#elif defined(OF_ARMV6) && defined(__GNUC__)
565 __asm__ (
566 "rev %0, %0"
567 : "=r" (i)
568 : "0" (i)
569 );
570#else
571 i = (i & UINT32_C(0xFF000000)) >> 24 |
572 (i & UINT32_C(0x00FF0000)) >> 8 |
573 (i & UINT32_C(0x0000FF00)) << 8 |
574 (i & UINT32_C(0x000000FF)) << 24;
575#endif
576 return i;
577}
578
579static OF_INLINE uint64_t OF_CONST_FUNC
580_OFByteSwap64NonConst(uint64_t i)
581{
582#if defined(OF_HAVE_BUILTIN_BSWAP64)
583 return __builtin_bswap64(i);
584#elif defined(OF_AMD64) && defined(__GNUC__)
585 __asm__ (
586 "bswap %0"
587 : "=r" (i)
588 : "0" (i)
589 );
590#elif defined(OF_X86) && defined(__GNUC__)
591 __asm__ (
592 "bswap {%%}eax\n\t"
593 "bswap {%%}edx\n\t"
594 "xchg{l} { %%eax, %%edx | edx, eax }"
595 : "=A" (i)
596 : "0" (i)
597 );
598#else
599 i = (uint64_t)_OFByteSwap32NonConst(
600 (uint32_t)(i & UINT32_C(0xFFFFFFFF))) << 32 |
601 _OFByteSwap32NonConst((uint32_t)(i >> 32));
602#endif
603 return i;
604}
605
606#if defined(__GNUC__) || defined(DOXYGEN)
613# define OFByteSwap16(i) \
614 (__builtin_constant_p(i) ? _OFByteSwap16Const(i) : _OFByteSwap16NonConst(i))
615
622# define OFByteSwap32(i) \
623 (__builtin_constant_p(i) ? _OFByteSwap32Const(i) : _OFByteSwap32NonConst(i))
624
631# define OFByteSwap64(i) \
632 (__builtin_constant_p(i) ? _OFByteSwap64Const(i) : _OFByteSwap64NonConst(i))
633#else
634# define OFByteSwap16(i) _OFByteSwap16Const(i)
635# define OFByteSwap32(i) _OFByteSwap32Const(i)
636# define OFByteSwap64(i) _OFByteSwap64Const(i)
637#endif
638
645static OF_INLINE uint32_t OF_CONST_FUNC
647{
648 uint32_t ret;
649 memcpy(&ret, &f, 4);
650 return ret;
651}
652
659static OF_INLINE float OF_CONST_FUNC
661{
662 float ret;
663 memcpy(&ret, &uInt32, 4);
664 return ret;
665}
666
673static OF_INLINE uint64_t OF_CONST_FUNC
675{
676 uint64_t ret;
677 memcpy(&ret, &d, 8);
678 return ret;
679}
680
687static OF_INLINE double OF_CONST_FUNC
689{
690 double ret;
691 memcpy(&ret, &uInt64, 8);
692 return ret;
693}
694
701static OF_INLINE float OF_CONST_FUNC
707
714static OF_INLINE double OF_CONST_FUNC
720
721#if defined(OF_BIG_ENDIAN) || defined(DOXYGEN)
729# define OFFromBigEndian16(i) (i)
730
738# define OFFromBigEndian32(i) (i)
739
747# define OFFromBigEndian64(i) (i)
748
756# define OFFromLittleEndian16(i) OFByteSwap16(i)
757
765# define OFFromLittleEndian32(i) OFByteSwap32(i)
766
774# define OFFromLittleEndian64(i) OFByteSwap64(i)
775
783# define OFToBigEndian16(i) (i)
784
792# define OFToBigEndian32(i) (i)
793
801# define OFToBigEndian64(i) (i)
802
810# define OFToLittleEndian16(i) OFByteSwap16(i)
811
819# define OFToLittleEndian32(i) OFByteSwap32(i)
820
828# define OFToLittleEndian64(i) OFByteSwap64(i)
829#else
830# define OFFromBigEndian16(i) OFByteSwap16(i)
831# define OFFromBigEndian32(i) OFByteSwap32(i)
832# define OFFromBigEndian64(i) OFByteSwap64(i)
833# define OFFromLittleEndian16(i) (i)
834# define OFFromLittleEndian32(i) (i)
835# define OFFromLittleEndian64(i) (i)
836# define OFToBigEndian16(i) OFByteSwap16(i)
837# define OFToBigEndian32(i) OFByteSwap32(i)
838# define OFToBigEndian64(i) OFByteSwap64(i)
839# define OFToLittleEndian16(i) (i)
840# define OFToLittleEndian32(i) (i)
841# define OFToLittleEndian64(i) (i)
842#endif
843
844#if defined(OF_FLOAT_BIG_ENDIAN) || defined(DOXYGEN)
851# define OFFromBigEndianFloat(f) (f)
852
859# define OFFromBigEndianDouble(d) (d)
860
867# define OFFromLittleEndianFloat(f) OFByteSwapFloat(f)
868
875# define OFFromLittleEndianDouble(d) OFByteSwapDouble(d)
876
883# define OFToBigEndianFloat(f) (f)
884
891# define OFToBigEndianDouble(d) (d)
892
899# define OFToLittleEndianFloat(f) OFByteSwapFloat(f)
900
907# define OFToLittleEndianDouble(d) OFByteSwapDouble(d)
908#else
909# define OFFromBigEndianFloat(f) OFByteSwapFloat(f)
910# define OFFromBigEndianDouble(d) OFByteSwapDouble(d)
911# define OFFromLittleEndianFloat(f) (f)
912# define OFFromLittleEndianDouble(d) (d)
913# define OFToBigEndianFloat(f) OFByteSwapFloat(f)
914# define OFToBigEndianDouble(d) OFByteSwapDouble(d)
915# define OFToLittleEndianFloat(f) (f)
916# define OFToLittleEndianDouble(d) (d)
917#endif
918
926#define OFRotateLeft(value, bits) \
927 (((bits) % (sizeof(value) * 8)) > 0 \
928 ? ((value) << ((bits) % (sizeof(value) * 8))) | \
929 ((value) >> (sizeof(value) * 8 - ((bits) % (sizeof(value) * 8)))) \
930 : (value))
931
939#define OFRotateRight(value, bits) \
940 (((bits) % (sizeof(value) * 8)) > 0 \
941 ? ((value) >> ((bits) % (sizeof(value) * 8))) | \
942 ((value) << (sizeof(value) * 8 - ((bits) % (sizeof(value) * 8)))) \
943 : (value))
944
952#define OFRoundUpToPowerOf2(pow2, value) \
953 (((value) + (pow2) - 1) & ~((pow2) - 1))
954
955#define OF_ULONG_BIT (sizeof(unsigned long) * CHAR_BIT)
956
957#if defined(OF_HAVE__FLOAT16) || defined(DOXYGEN)
961__extension__ typedef _Float16 OFFloat16;
962
963static OF_INLINE OFFloat16
964OFFloat16FromFloat(float value)
965{
966 return value;
967}
968
969static OF_INLINE float
970OFFloat16ToFloat(OFFloat16 value)
971{
972 return value;
973}
974#else
975typedef uint16_t OFFloat16;
976
977static OF_INLINE OFFloat16
978OFFloat16FromFloat(float value)
979{
980 uint32_t uint32 = OFBitConvertFloatToUInt32(value);
981 uint16_t uint16;
982
983# if (defined(OF_BIG_ENDIAN) && !defined(OF_FLOAT_BIG_ENDIAN)) || \
984 (!defined(OF_BIG_ENDIAN) && defined(OF_FLOAT_BIG_ENDIAN))
985 uint32 = OFByteSwap32(uint32);
986# endif
987
988 uint16 = (uint32 >> 16) & 0x8000;
989
990 if (uint32 & 0x7F800000)
991 uint16 |= (((uint32 & 0x7F800000) - 0x38000000) >> 13) & 0x7C00;
992
993 uint16 |= (uint32 >> 13) & 0x3FF;
994
995# if (defined(OF_BIG_ENDIAN) && !defined(OF_FLOAT_BIG_ENDIAN)) || \
996 (!defined(OF_BIG_ENDIAN) && defined(OF_FLOAT_BIG_ENDIAN))
997 uint16 = OFByteSwap16(uint16);
998# endif
999
1000 return uint16;
1001}
1002
1003static OF_INLINE float
1004OFFloat16ToFloat(OFFloat16 value)
1005{
1006 uint32_t uint32;
1007
1008# if (defined(OF_BIG_ENDIAN) && !defined(OF_FLOAT_BIG_ENDIAN)) || \
1009 (!defined(OF_BIG_ENDIAN) && defined(OF_FLOAT_BIG_ENDIAN))
1010 value = OFByteSwap16(value);
1011# endif
1012
1013 uint32 = (value & 0x8000) << 16;
1014
1015 if (value & 0x7C00)
1016 uint32 |= (((value & 0x7C00) + 0x1C000) & 0x3FC00) << 13;
1017
1018 uint32 |= (value & 0x3FF) << 13;
1019
1020# if (defined(OF_BIG_ENDIAN) && !defined(OF_FLOAT_BIG_ENDIAN)) || \
1021 (!defined(OF_BIG_ENDIAN) && defined(OF_FLOAT_BIG_ENDIAN))
1022 uint32 = OFByteSwap32(uint32);
1023# endif
1024
1025 return OFBitConvertUInt32ToFloat(uint32);
1026}
1027#endif
1028
1029static OF_INLINE bool
1030OFBitSetIsSet(unsigned long *_Nonnull storage, size_t idx)
1031{
1032 return storage[idx / OF_ULONG_BIT] & (1ul << (idx % OF_ULONG_BIT));
1033}
1034
1035static OF_INLINE void
1036OFBitSetSet(unsigned long *_Nonnull storage, size_t idx)
1037{
1038 storage[idx / OF_ULONG_BIT] |= (1ul << (idx % OF_ULONG_BIT));
1039}
1040
1041static OF_INLINE void
1042OFBitSetClear(unsigned long *_Nonnull storage, size_t idx)
1043{
1044 storage[idx / OF_ULONG_BIT] &= ~(1ul << (idx % OF_ULONG_BIT));
1045}
1046
1047static OF_INLINE void
1048OFZeroMemory(void *_Nonnull buffer_, size_t length)
1049{
1050 volatile unsigned char *buffer = (volatile unsigned char *)buffer_;
1051
1052 while (buffer < (unsigned char *)buffer_ + length)
1053 *buffer++ = '\0';
1054}
1055
1056static OF_INLINE bool
1057OFASCIIIsAlpha(char c)
1058{
1059 return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'));
1060}
1061
1062static OF_INLINE bool
1063OFASCIIIsDigit(char c)
1064{
1065 return (c >= '0' && c <= '9');
1066}
1067
1068static OF_INLINE bool
1069OFASCIIIsAlnum(char c)
1070{
1071 return (OFASCIIIsAlpha(c) || OFASCIIIsDigit(c));
1072}
1073
1074static OF_INLINE bool
1075OFASCIIIsSpace(char c)
1076{
1077 return (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' ||
1078 c == '\v');
1079}
1080
1081static OF_INLINE char
1082OFASCIIToUpper(char c)
1083{
1084 return (c >= 'a' && c <= 'z' ? 'A' + (c - 'a') : c);
1085}
1086
1087static OF_INLINE char
1088OFASCIIToLower(char c)
1089{
1090 return (c >= 'A' && c <= 'Z' ? 'a' + (c - 'A') : c);
1091}
1092#endif
A class for storing constant strings using the @"" literal.
Definition OFConstantString.h:42
static OF_INLINE float OF_CONST_FUNC OFBitConvertUInt32ToFloat(uint32_t uInt32)
Bit-converts the specified uint32_t to a float.
Definition macros.h:660
#define OFByteSwap32(i)
Byte swaps the specified 32 bit integer.
Definition macros.h:622
static OF_INLINE double OF_CONST_FUNC OFBitConvertUInt64ToDouble(uint64_t uInt64)
Bit-converts the specified uint64_t to a double.
Definition macros.h:688
__extension__ typedef _Float16 OFFloat16
A type for 16 bit floating point numbers.
Definition macros.h:961
#define OFByteSwap64(i)
Byte swaps the specified 64 bit integer.
Definition macros.h:631
static OF_INLINE double OF_CONST_FUNC OFByteSwapDouble(double d)
Byte swaps the specified double.
Definition macros.h:715
static OF_INLINE float OF_CONST_FUNC OFByteSwapFloat(float f)
Byte swaps the specified float.
Definition macros.h:702
#define OFByteSwap16(i)
Byte swaps the specified 16 bit integer.
Definition macros.h:613
static OF_INLINE uint64_t OF_CONST_FUNC OFBitConvertDoubleToUInt64(double d)
Bit-converts the specified double to a uint64_t.
Definition macros.h:674
static OF_INLINE uint32_t OF_CONST_FUNC OFBitConvertFloatToUInt32(float f)
Bit-converts the specified float to a uint32_t.
Definition macros.h:646