ObjFW
Loading...
Searching...
No Matches
macros.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2008-2025 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
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# else
105# define OF_VISIBILITY_HIDDEN
106# endif
107#else
108# define OF_INLINE inline
109# define OF_LIKELY(cond) (cond)
110# define OF_UNLIKELY(cond) (cond)
111# define OF_CONST_FUNC
112# define OF_NO_RETURN_FUNC
113# define OF_WEAK_REF(sym)
114# define OF_VISIBILITY_HIDDEN
115#endif
116
117#if __STDC_VERSION__ >= 201112L
118# define OF_ALIGN(size) _Alignas(size)
119# define OF_ALIGNOF(type) _Alignof(type)
120# define OF_ALIGNAS(type) _Alignas(type)
121#else
122# define OF_ALIGN(size) __attribute__((__aligned__(size)))
123# define OF_ALIGNOF(type) __alignof__(type)
124# define OF_ALIGNAS(type) OF_ALIGN(OF_ALIGNOF(type))
125#endif
126
127#ifdef __BIGGEST_ALIGNMENT__
128# define OF_BIGGEST_ALIGNMENT __BIGGEST_ALIGNMENT__
129#else
130/* Hopefully no arch needs more than 16 byte alignment */
131# define OF_BIGGEST_ALIGNMENT 16
132#endif
133/*
134 * We use SSE inline assembly on AMD64 and x86, so it must never be smaller
135 * than 16.
136 */
137#if (defined(OF_AMD64) || defined(OF_X86)) && OF_BIGGEST_ALIGNMENT < 16
138# undef OF_BIGGEST_ALIGNMENT
139# define OF_BIGGEST_ALIGNMENT 16
140#endif
141
142#define OF_PREPROCESSOR_CONCAT2(a, b) a##b
143#define OF_PREPROCESSOR_CONCAT(a, b) OF_PREPROCESSOR_CONCAT2(a, b)
144
145#if __OBJFW_RUNTIME_ABI__ || (defined(OF_APPLE_RUNTIME) && defined(__OBJC2__))
146# define OF_HAVE_NONFRAGILE_IVARS
147#endif
148
149#ifdef OF_HAVE_NONFRAGILE_IVARS
150# define OF_RESERVE_IVARS(cls, num)
151#else
152# define OF_RESERVE_IVARS(cls, num) \
153 @private \
154 void *OF_PREPROCESSOR_CONCAT(_reserved_, cls)[num];
155#endif
156
157#ifdef __GNUC__
158# define OF_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
159#else
160# define OF_GCC_VERSION 0
161#endif
162
163#define OF_STRINGIFY(s) OF_STRINGIFY2(s)
164#define OF_STRINGIFY2(s) #s
165
166#ifndef __has_feature
167# define __has_feature(x) 0
168#endif
169
170#ifndef __has_attribute
171# define __has_attribute(x) 0
172#endif
173
174#if __has_feature(objc_bool)
175# undef YES
176# define YES __objc_yes
177# undef NO
178# define NO __objc_no
179# ifndef __cplusplus
180# undef true
181# define true ((bool)1)
182# undef false
183# define false ((bool)0)
184# endif
185#endif
186
187#if !__has_feature(objc_instancetype)
188# define instancetype id
189#endif
190
191#if __has_feature(blocks)
192# define OF_HAVE_BLOCKS
193#endif
194
195#if __has_feature(objc_arc)
196# define OF_RETURNS_RETAINED __attribute__((__ns_returns_retained__))
197# define OF_RETURNS_NOT_RETAINED __attribute__((__ns_returns_not_retained__))
198# define OF_RETURNS_INNER_POINTER \
199 __attribute__((__objc_returns_inner_pointer__))
200# define OF_CONSUMED __attribute__((__ns_consumed__))
201# define OF_WEAK_UNAVAILABLE __attribute__((__objc_arc_weak_unavailable__))
202#else
203# define OF_RETURNS_RETAINED
204# define OF_RETURNS_NOT_RETAINED
205# define OF_RETURNS_INNER_POINTER
206# define OF_CONSUMED
207# define OF_WEAK_UNAVAILABLE
208/*
209 * undef them first, as new Clang versions have these as built-in defines even
210 * when ARC is disabled.
211 */
212# undef __unsafe_unretained
213# undef __bridge
214# undef __autoreleasing
215# define __unsafe_unretained
216# define __bridge
217# define __autoreleasing
218#endif
219
220#if __has_feature(objc_generics)
221# define OF_HAVE_GENERICS
222# define OF_GENERIC(...) <__VA_ARGS__>
223#else
224# define OF_GENERIC(...)
225#endif
226
227#if __has_feature(nullability)
228# define OF_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin")
229# define OF_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end")
230# define OF_NULLABLE_PROPERTY(...) (__VA_ARGS__, nullable)
231# define OF_NULL_RESETTABLE_PROPERTY(...) (__VA_ARGS__, null_resettable)
232#else
233# define OF_ASSUME_NONNULL_BEGIN
234# define OF_ASSUME_NONNULL_END
235# define _Nonnull
236# define _Nullable
237# define _Null_unspecified
238# define OF_NULLABLE_PROPERTY
239# define OF_NULL_RESETTABLE_PROPERTY
240# define nonnull
241# define nullable
242# define null_unspecified
243#endif
244
245#if __has_feature(objc_kindof)
246# define OF_KINDOF(class_) __kindof class_
247#else
248# define OF_KINDOF(class_) id
249#endif
250
251#if __has_feature(objc_class_property)
252# define OF_HAVE_CLASS_PROPERTIES
253#endif
254
255#if defined(__clang__) || OF_GCC_VERSION >= 405
256# define OF_UNREACHABLE __builtin_unreachable();
257#else
258# define OF_UNREACHABLE abort();
259#endif
260
261#if defined(__clang__) || OF_GCC_VERSION >= 406
262# define OF_SENTINEL __attribute__((__sentinel__))
263# define OF_NO_RETURN __attribute__((__noreturn__))
264#else
265# define OF_SENTINEL
266# define OF_NO_RETURN
267#endif
268
269#ifdef __clang__
270# define OF_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
271#else
272# define OF_WARN_UNUSED_RESULT
273#endif
274
275#if __has_attribute(__unavailable__)
276# define OF_UNAVAILABLE __attribute__((__unavailable__))
277#else
278# define OF_UNAVAILABLE
279#endif
280
281#if __has_attribute(__objc_requires_super__)
282# define OF_REQUIRES_SUPER __attribute__((__objc_requires_super__))
283#else
284# define OF_REQUIRES_SUPER
285#endif
286
287#if __has_attribute(__objc_root_class__)
288# define OF_ROOT_CLASS __attribute__((__objc_root_class__))
289#else
290# define OF_ROOT_CLASS
291#endif
292
293#if __has_attribute(__objc_subclassing_restricted__)
294# define OF_SUBCLASSING_RESTRICTED \
295 __attribute__((__objc_subclassing_restricted__))
296#else
297# define OF_SUBCLASSING_RESTRICTED
298#endif
299
300#if __has_attribute(__objc_method_family__)
301# define OF_METHOD_FAMILY(f) __attribute__((__objc_method_family__(f)))
302#else
303# define OF_METHOD_FAMILY(f)
304#endif
305
306#if __has_attribute(__objc_designated_initializer__)
307# define OF_DESIGNATED_INITIALIZER \
308 __attribute__((__objc_designated_initializer__))
309#else
310# define OF_DESIGNATED_INITIALIZER
311#endif
312
313#if defined(__clang__) || OF_GCC_VERSION >= 405
314# define OF_DEPRECATED(project, major, minor, msg) \
315 __attribute__((__deprecated__("Deprecated in " #project " " \
316 #major "." #minor ": " msg)))
317#elif defined(__GNUC__)
318# define OF_DEPRECATED(project, major, minor, msg) \
319 __attribute__((__deprecated__))
320#else
321# define OF_DEPRECATED(project, major, minor, msg)
322#endif
323
324#if __has_attribute(__objc_boxable__)
325# define OF_BOXABLE __attribute__((__objc_boxable__))
326#else
327# define OF_BOXABLE
328#endif
329
330#if __has_attribute(__swift_name__)
331# define OF_SWIFT_NAME(name) __attribute__((__swift_name__(name)))
332#else
333# define OF_SWIFT_NAME(name)
334#endif
335
336#if __has_attribute(__objc_direct__) && defined(OF_APPLE_RUNTIME)
337# define OF_DIRECT __attribute__((__objc_direct__))
338# define OF_DIRECT_PROPERTY(...) (__VA_ARGS__, direct)
339#else
340# define OF_DIRECT
341# define OF_DIRECT_PROPERTY
342#endif
343#if __has_attribute(__objc_direct_members__) && defined(OF_APPLE_RUNTIME)
344# define OF_DIRECT_MEMBERS __attribute__((__objc_direct_members__))
345#else
346# define OF_DIRECT_MEMBERS
347#endif
348
349#ifdef OF_APPLE_RUNTIME
350# if defined(OF_AMD64) || defined(OF_X86) || defined(OF_ARM64) || \
351 defined(OF_ARM) || defined(OF_POWERPC)
352# define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR
353# define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET
354# endif
355#else
356# if defined(OF_ELF)
357# if defined(OF_AMD64) || defined(OF_X86) || \
358 defined(OF_ARM64) || defined(OF_ARM) || \
359 defined(OF_POWERPC) || defined(OF_POWERPC64) || \
360 defined(OF_MIPS64_N64) || defined(OF_MIPS) || \
361 defined(OF_SPARC64) || defined(OF_SPARC) || \
362 defined(OF_RISCV64) || defined(OF_LOONGARCH64)
363# define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR
364# if __OBJFW_RUNTIME_ABI__ >= 800
365# define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET
366# endif
367# endif
368# elif defined(OF_MACH_O)
369# if defined(OF_AMD64)
370# define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR
371# if __OBJFW_RUNTIME_ABI__ >= 800
372# define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET
373# endif
374# endif
375# elif defined(OF_WINDOWS)
376# if defined(OF_AMD64) || defined(OF_X86) || defined(OF_ARM64)
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# endif
383#endif
384
385#define OFMaxRetainCount UINT_MAX
386
387#ifdef OBJC_COMPILING_RUNTIME
388# define OFEnsure(cond) \
389 do { \
390 if OF_UNLIKELY (!(cond)) \
391 objc_error("ObjFWRT @ " __FILE__ ":" \
392 OF_STRINGIFY(__LINE__), \
393 "Failed to ensure condition:\n" #cond); \
394 } while(0)
395#else
396@class OFConstantString;
397# ifdef __cplusplus
398extern "C" {
399# endif
400extern void OFLog(OFConstantString *_Nonnull, ...);
401# ifdef __cplusplus
402}
403# endif
404# define OFEnsure(cond) \
405 do { \
406 if OF_UNLIKELY (!(cond)) { \
407 OFLog(@"Failed to ensure condition in " \
408 @__FILE__ ":%d: " @#cond, __LINE__); \
409 abort(); \
410 } \
411 } while (0)
412#endif
413
414#ifndef NDEBUG
415# define OFAssert(...) OFEnsure(__VA_ARGS__)
416#else
417# define OFAssert(...)
418#endif
419
420#define OF_UNRECOGNIZED_SELECTOR OFMethodNotFound(self, _cmd);
421#if __has_feature(objc_arc)
422# define OF_INVALID_INIT_METHOD OFMethodNotFound(self, _cmd);
423#else
424# define OF_INVALID_INIT_METHOD \
425 @try { \
426 OFMethodNotFound(self, _cmd); \
427 } @catch (id e) { \
428 [self release]; \
429 @throw e; \
430 } \
431 \
432 abort();
433#endif
434#ifdef __clang__
435# define OF_DEALLOC_UNSUPPORTED \
436 [self doesNotRecognizeSelector: _cmd]; \
437 \
438 abort(); \
439 \
440 _Pragma("clang diagnostic push"); \
441 _Pragma("clang diagnostic ignored \"-Wunreachable-code\""); \
442 [super dealloc]; /* Get rid of a stupid warning */ \
443 _Pragma("clang diagnostic pop");
444#else
445# define OF_DEALLOC_UNSUPPORTED \
446 [self doesNotRecognizeSelector: _cmd]; \
447 \
448 abort(); \
449 \
450 [super dealloc]; /* Get rid of a stupid warning */
451#endif
452#define OF_SINGLETON_METHODS \
453 - (instancetype)autorelease \
454 { \
455 return self; \
456 } \
457 \
458 - (instancetype)retain \
459 { \
460 return self; \
461 } \
462 \
463 - (void)release \
464 { \
465 } \
466 \
467 - (unsigned int)retainCount \
468 { \
469 return OFMaxRetainCount; \
470 } \
471 \
472 - (void)dealloc \
473 { \
474 OF_DEALLOC_UNSUPPORTED \
475 }
476
477#define OF_CONSTRUCTOR(prio) \
478 static void __attribute__((__constructor__(prio))) \
479 OF_PREPROCESSOR_CONCAT(constructor, __LINE__)(void)
480#define OF_DESTRUCTOR(prio) \
481 static void __attribute__((__destructor__(prio))) \
482 OF_PREPROCESSOR_CONCAT(destructor, __LINE__)(void)
483
484static OF_INLINE uint16_t OF_CONST_FUNC
485_OFByteSwap16Const(uint16_t i)
486{
487 return (i & UINT16_C(0xFF00)) >> 8 | (i & UINT16_C(0x00FF)) << 8;
488}
489
490static OF_INLINE uint32_t OF_CONST_FUNC
491_OFByteSwap32Const(uint32_t i)
492{
493 return (i & UINT32_C(0xFF000000)) >> 24 |
494 (i & UINT32_C(0x00FF0000)) >> 8 |
495 (i & UINT32_C(0x0000FF00)) << 8 |
496 (i & UINT32_C(0x000000FF)) << 24;
497}
498
499static OF_INLINE uint64_t OF_CONST_FUNC
500_OFByteSwap64Const(uint64_t i)
501{
502 return (i & UINT64_C(0xFF00000000000000)) >> 56 |
503 (i & UINT64_C(0x00FF000000000000)) >> 40 |
504 (i & UINT64_C(0x0000FF0000000000)) >> 24 |
505 (i & UINT64_C(0x000000FF00000000)) >> 8 |
506 (i & UINT64_C(0x00000000FF000000)) << 8 |
507 (i & UINT64_C(0x0000000000FF0000)) << 24 |
508 (i & UINT64_C(0x000000000000FF00)) << 40 |
509 (i & UINT64_C(0x00000000000000FF)) << 56;
510}
511
512static OF_INLINE uint16_t OF_CONST_FUNC
513_OFByteSwap16NonConst(uint16_t i)
514{
515#if defined(OF_HAVE_BUILTIN_BSWAP16)
516 return __builtin_bswap16(i);
517#elif (defined(OF_AMD64) || defined(OF_X86)) && defined(__GNUC__)
518 __asm__ (
519 "xchg{b} { %h0, %b0 | %b0, %h0 }"
520 : "=Q" (i)
521 : "0" (i)
522 );
523#elif defined(OF_POWERPC) && defined(__GNUC__)
524 __asm__ (
525 "lhbrx %0, 0, %1"
526 : "=r" (i)
527 : "r" (&i),
528 "m" (i)
529 );
530#elif defined(OF_ARMV6) && defined(__GNUC__)
531 __asm__ (
532 "rev16 %0, %0"
533 : "=r" (i)
534 : "0" (i)
535 );
536#else
537 i = (i & UINT16_C(0xFF00)) >> 8 |
538 (i & UINT16_C(0x00FF)) << 8;
539#endif
540 return i;
541}
542
543static OF_INLINE uint32_t OF_CONST_FUNC
544_OFByteSwap32NonConst(uint32_t i)
545{
546#if defined(OF_HAVE_BUILTIN_BSWAP32)
547 return __builtin_bswap32(i);
548#elif (defined(OF_AMD64) || defined(OF_X86)) && defined(__GNUC__)
549 __asm__ (
550 "bswap %0"
551 : "=q" (i)
552 : "0" (i)
553 );
554#elif defined(OF_POWERPC) && defined(__GNUC__)
555 __asm__ (
556 "lwbrx %0, 0, %1"
557 : "=r" (i)
558 : "r" (&i),
559 "m" (i)
560 );
561#elif defined(OF_ARMV6) && defined(__GNUC__)
562 __asm__ (
563 "rev %0, %0"
564 : "=r" (i)
565 : "0" (i)
566 );
567#else
568 i = (i & UINT32_C(0xFF000000)) >> 24 |
569 (i & UINT32_C(0x00FF0000)) >> 8 |
570 (i & UINT32_C(0x0000FF00)) << 8 |
571 (i & UINT32_C(0x000000FF)) << 24;
572#endif
573 return i;
574}
575
576static OF_INLINE uint64_t OF_CONST_FUNC
577_OFByteSwap64NonConst(uint64_t i)
578{
579#if defined(OF_HAVE_BUILTIN_BSWAP64)
580 return __builtin_bswap64(i);
581#elif defined(OF_AMD64) && defined(__GNUC__)
582 __asm__ (
583 "bswap %0"
584 : "=r" (i)
585 : "0" (i)
586 );
587#elif defined(OF_X86) && defined(__GNUC__)
588 __asm__ (
589 "bswap {%%}eax\n\t"
590 "bswap {%%}edx\n\t"
591 "xchg{l} { %%eax, %%edx | edx, eax }"
592 : "=A" (i)
593 : "0" (i)
594 );
595#else
596 i = (uint64_t)_OFByteSwap32NonConst(
597 (uint32_t)(i & UINT32_C(0xFFFFFFFF))) << 32 |
598 _OFByteSwap32NonConst((uint32_t)(i >> 32));
599#endif
600 return i;
601}
602
603#if defined(__GNUC__) || defined(DOXYGEN)
610# define OFByteSwap16(i) \
611 (__builtin_constant_p(i) ? _OFByteSwap16Const(i) : _OFByteSwap16NonConst(i))
612
619# define OFByteSwap32(i) \
620 (__builtin_constant_p(i) ? _OFByteSwap32Const(i) : _OFByteSwap32NonConst(i))
621
628# define OFByteSwap64(i) \
629 (__builtin_constant_p(i) ? _OFByteSwap64Const(i) : _OFByteSwap64NonConst(i))
630#else
631# define OFByteSwap16(i) _OFByteSwap16Const(i)
632# define OFByteSwap32(i) _OFByteSwap32Const(i)
633# define OFByteSwap64(i) _OFByteSwap64Const(i)
634#endif
635
642static OF_INLINE uint32_t OF_CONST_FUNC
644{
645 uint32_t ret;
646 memcpy(&ret, &f, 4);
647 return ret;
648}
649
656static OF_INLINE float OF_CONST_FUNC
658{
659 float ret;
660 memcpy(&ret, &uInt32, 4);
661 return ret;
662}
663
670static OF_INLINE uint64_t OF_CONST_FUNC
672{
673 uint64_t ret;
674 memcpy(&ret, &d, 8);
675 return ret;
676}
677
684static OF_INLINE double OF_CONST_FUNC
686{
687 double ret;
688 memcpy(&ret, &uInt64, 8);
689 return ret;
690}
691
698static OF_INLINE float OF_CONST_FUNC
704
711static OF_INLINE double OF_CONST_FUNC
717
718#if defined(OF_BIG_ENDIAN) || defined(DOXYGEN)
726# define OFFromBigEndian16(i) (i)
727
735# define OFFromBigEndian32(i) (i)
736
744# define OFFromBigEndian64(i) (i)
745
753# define OFFromLittleEndian16(i) OFByteSwap16(i)
754
762# define OFFromLittleEndian32(i) OFByteSwap32(i)
763
771# define OFFromLittleEndian64(i) OFByteSwap64(i)
772
780# define OFToBigEndian16(i) (i)
781
789# define OFToBigEndian32(i) (i)
790
798# define OFToBigEndian64(i) (i)
799
807# define OFToLittleEndian16(i) OFByteSwap16(i)
808
816# define OFToLittleEndian32(i) OFByteSwap32(i)
817
825# define OFToLittleEndian64(i) OFByteSwap64(i)
826#else
827# define OFFromBigEndian16(i) OFByteSwap16(i)
828# define OFFromBigEndian32(i) OFByteSwap32(i)
829# define OFFromBigEndian64(i) OFByteSwap64(i)
830# define OFFromLittleEndian16(i) (i)
831# define OFFromLittleEndian32(i) (i)
832# define OFFromLittleEndian64(i) (i)
833# define OFToBigEndian16(i) OFByteSwap16(i)
834# define OFToBigEndian32(i) OFByteSwap32(i)
835# define OFToBigEndian64(i) OFByteSwap64(i)
836# define OFToLittleEndian16(i) (i)
837# define OFToLittleEndian32(i) (i)
838# define OFToLittleEndian64(i) (i)
839#endif
840
841#if defined(OF_FLOAT_BIG_ENDIAN) || defined(DOXYGEN)
848# define OFFromBigEndianFloat(f) (f)
849
856# define OFFromBigEndianDouble(d) (d)
857
864# define OFFromLittleEndianFloat(f) OFByteSwapFloat(f)
865
872# define OFFromLittleEndianDouble(d) OFByteSwapDouble(d)
873
880# define OFToBigEndianFloat(f) (f)
881
888# define OFToBigEndianDouble(d) (d)
889
896# define OFToLittleEndianFloat(f) OFByteSwapFloat(f)
897
904# define OFToLittleEndianDouble(d) OFByteSwapDouble(d)
905#else
906# define OFFromBigEndianFloat(f) OFByteSwapFloat(f)
907# define OFFromBigEndianDouble(d) OFByteSwapDouble(d)
908# define OFFromLittleEndianFloat(f) (f)
909# define OFFromLittleEndianDouble(d) (d)
910# define OFToBigEndianFloat(f) OFByteSwapFloat(f)
911# define OFToBigEndianDouble(d) OFByteSwapDouble(d)
912# define OFToLittleEndianFloat(f) (f)
913# define OFToLittleEndianDouble(d) (d)
914#endif
915
923#define OFRotateLeft(value, bits) \
924 (((bits) % (sizeof(value) * 8)) > 0 \
925 ? ((value) << ((bits) % (sizeof(value) * 8))) | \
926 ((value) >> (sizeof(value) * 8 - ((bits) % (sizeof(value) * 8)))) \
927 : (value))
928
936#define OFRotateRight(value, bits) \
937 (((bits) % (sizeof(value) * 8)) > 0 \
938 ? ((value) >> ((bits) % (sizeof(value) * 8))) | \
939 ((value) << (sizeof(value) * 8 - ((bits) % (sizeof(value) * 8)))) \
940 : (value))
941
949#define OFRoundUpToPowerOf2(pow2, value) \
950 (((value) + (pow2) - 1) & ~((pow2) - 1))
951
952#define OF_ULONG_BIT (sizeof(unsigned long) * CHAR_BIT)
953
954static OF_INLINE bool
955OFBitSetIsSet(unsigned long *_Nonnull storage, size_t idx)
956{
957 return storage[idx / OF_ULONG_BIT] & (1ul << (idx % OF_ULONG_BIT));
958}
959
960static OF_INLINE void
961OFBitSetSet(unsigned long *_Nonnull storage, size_t idx)
962{
963 storage[idx / OF_ULONG_BIT] |= (1ul << (idx % OF_ULONG_BIT));
964}
965
966static OF_INLINE void
967OFBitSetClear(unsigned long *_Nonnull storage, size_t idx)
968{
969 storage[idx / OF_ULONG_BIT] &= ~(1ul << (idx % OF_ULONG_BIT));
970}
971
972static OF_INLINE void
973OFZeroMemory(void *_Nonnull buffer_, size_t length)
974{
975 volatile unsigned char *buffer = (volatile unsigned char *)buffer_;
976
977 while (buffer < (unsigned char *)buffer_ + length)
978 *buffer++ = '\0';
979}
980
981static OF_INLINE bool
982OFASCIIIsAlpha(char c)
983{
984 return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'));
985}
986
987static OF_INLINE bool
988OFASCIIIsDigit(char c)
989{
990 return (c >= '0' && c <= '9');
991}
992
993static OF_INLINE bool
994OFASCIIIsAlnum(char c)
995{
996 return (OFASCIIIsAlpha(c) || OFASCIIIsDigit(c));
997}
998
999static OF_INLINE bool
1000OFASCIIIsSpace(char c)
1001{
1002 return (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' ||
1003 c == '\v');
1004}
1005
1006static OF_INLINE char
1007OFASCIIToUpper(char c)
1008{
1009 return (c >= 'a' && c <= 'z' ? 'A' + (c - 'a') : c);
1010}
1011
1012static OF_INLINE char
1013OFASCIIToLower(char c)
1014{
1015 return (c >= 'A' && c <= 'Z' ? 'a' + (c - 'A') : c);
1016}
1017#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:657
#define OFByteSwap32(i)
Byte swaps the specified 32 bit integer.
Definition macros.h:619
static OF_INLINE double OF_CONST_FUNC OFBitConvertUInt64ToDouble(uint64_t uInt64)
Bit-converts the specified uint64_t to a double.
Definition macros.h:685
#define OFByteSwap64(i)
Byte swaps the specified 64 bit integer.
Definition macros.h:628
static OF_INLINE double OF_CONST_FUNC OFByteSwapDouble(double d)
Byte swaps the specified double.
Definition macros.h:712
static OF_INLINE float OF_CONST_FUNC OFByteSwapFloat(float f)
Byte swaps the specified float.
Definition macros.h:699
static OF_INLINE uint64_t OF_CONST_FUNC OFBitConvertDoubleToUInt64(double d)
Bit-converts the specified double to a uint64_t.
Definition macros.h:671
static OF_INLINE uint32_t OF_CONST_FUNC OFBitConvertFloatToUInt32(float f)
Bit-converts the specified float to a uint32_t.
Definition macros.h:643