ObjFW
Loading...
Searching...
No Matches
macros.h
1/*
2 * Copyright (c) 2008-2024 Jonathan Schleifer <js@nil.im>
3 *
4 * All rights reserved.
5 *
6 * This file is part of ObjFW. It may be distributed under the terms of the
7 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
8 * the packaging of this file.
9 *
10 * Alternatively, it may be distributed under the terms of the GNU General
11 * Public License, either version 2 or 3, which can be found in the file
12 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
13 * file.
14 */
15
16#ifndef OBJFW_MACROS_H
17#define OBJFW_MACROS_H
18
19#include "objfw-defs.h"
20
21#ifndef __STDC_LIMIT_MACROS
22# define __STDC_LIMIT_MACROS
23#endif
24#ifndef __STDC_CONSTANT_MACROS
25# define __STDC_CONSTANT_MACROS
26#endif
27
28#include <limits.h>
29#include <stdbool.h>
30#include <stddef.h>
31#include <stdint.h>
32#include <stdio.h>
33#include <stdlib.h>
34#include <string.h>
35
36#include <sys/time.h>
37
38#include "platform.h"
39
40#ifdef OF_OBJFW_RUNTIME
41# ifdef OF_COMPILING_OBJFW
42# include "ObjFWRT.h"
43# else
44# include <ObjFWRT/ObjFWRT.h>
45# endif
46#endif
47#ifdef OF_APPLE_RUNTIME
48# include <objc/objc.h>
49# include <objc/runtime.h>
50# include <objc/message.h>
51#endif
52
53#if defined(__GNUC__)
54# define restrict __restrict__
55#elif __STDC_VERSION__ < 199901L
56# define restrict
57#endif
58
59#if __STDC_VERSION__ >= 201112L && !defined(static_assert)
60/* C11 compiler, but old libc */
61# define static_assert _Static_assert
62#endif
63
64#if defined(OF_HAVE__THREAD_LOCAL)
65# define OF_HAVE_COMPILER_TLS
66# ifdef OF_HAVE_THREADS_H
67# include <threads.h>
68# ifdef OF_AIX
69/* AIX has a bug where thread_local is defined to "Thread_local;". */
70# undef thread_local
71# define thread_local _Thread_local
72# endif
73# else
74# define thread_local _Thread_local
75# endif
76#elif defined(OF_HAVE___THREAD)
77# define OF_HAVE_COMPILER_TLS
78# define thread_local __thread
79#endif
80
81/*
82 * Do not use compiler TLS when targeting the iOS simulator, as the iOS 9
83 * simulator does not support it (fails at runtime).
84 */
85#if defined(OF_HAVE_COMPILER_TLS) && defined(OF_IOS) && defined(OF_X86)
86# undef OF_HAVE_COMPILER_TLS
87#endif
88
89#ifdef __GNUC__
90# define OF_INLINE inline __attribute__((__always_inline__))
91# define OF_LIKELY(cond) (__builtin_expect(!!(cond), 1))
92# define OF_UNLIKELY(cond) (__builtin_expect(!!(cond), 0))
93# define OF_CONST_FUNC __attribute__((__const__))
94# define OF_NO_RETURN_FUNC __attribute__((__noreturn__))
95# define OF_WEAK_REF(sym) __attribute__((__weakref__(sym)))
96#else
97# define OF_INLINE inline
98# define OF_LIKELY(cond) (cond)
99# define OF_UNLIKELY(cond) (cond)
100# define OF_CONST_FUNC
101# define OF_NO_RETURN_FUNC
102# define OF_WEAK_REF(sym)
103#endif
104
105#if __STDC_VERSION__ >= 201112L
106# define OF_ALIGNOF(type) _Alignof(type)
107# define OF_ALIGNAS(type) _Alignas(type)
108#else
109# define OF_ALIGNOF(type) __alignof__(type)
110# define OF_ALIGNAS(type) __attribute__((__aligned__(__alignof__(type))))
111#endif
112
113#if __STDC_VERSION__ >= 201112L && defined(OF_HAVE_MAX_ALIGN_T)
114# define OF_BIGGEST_ALIGNMENT _Alignof(max_align_t)
115#else
116# ifdef __BIGGEST_ALIGNMENT__
117# define OF_BIGGEST_ALIGNMENT __BIGGEST_ALIGNMENT__
118# else
119# /* Hopefully no arch needs more than 16 byte alignment */
120# define OF_BIGGEST_ALIGNMENT 16
121# endif
122#endif
123
124#define OF_PREPROCESSOR_CONCAT2(a, b) a##b
125#define OF_PREPROCESSOR_CONCAT(a, b) OF_PREPROCESSOR_CONCAT2(a, b)
126
127#if __OBJFW_RUNTIME_ABI__ || (defined(OF_APPLE_RUNTIME) && defined(__OBJC2__))
128# define OF_HAVE_NONFRAGILE_IVARS
129#endif
130
131#ifdef OF_HAVE_NONFRAGILE_IVARS
132# define OF_RESERVE_IVARS(cls, num)
133#else
134# define OF_RESERVE_IVARS(cls, num) \
135 @private \
136 void *OF_PREPROCESSOR_CONCAT(_reserved_, cls)[num];
137#endif
138
139#ifdef __GNUC__
140# define OF_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
141#else
142# define OF_GCC_VERSION 0
143#endif
144
145#define OF_STRINGIFY(s) OF_STRINGIFY2(s)
146#define OF_STRINGIFY2(s) #s
147
148#ifndef __has_feature
149# define __has_feature(x) 0
150#endif
151
152#ifndef __has_attribute
153# define __has_attribute(x) 0
154#endif
155
156#if __has_feature(objc_bool)
157# undef YES
158# define YES __objc_yes
159# undef NO
160# define NO __objc_no
161# ifndef __cplusplus
162# undef true
163# define true ((bool)1)
164# undef false
165# define false ((bool)0)
166# endif
167#endif
168
169#if !__has_feature(objc_instancetype)
170# define instancetype id
171#endif
172
173#if __has_feature(blocks)
174# define OF_HAVE_BLOCKS
175#endif
176
177#if __has_feature(objc_arc)
178# define OF_RETURNS_RETAINED __attribute__((__ns_returns_retained__))
179# define OF_RETURNS_NOT_RETAINED __attribute__((__ns_returns_not_retained__))
180# define OF_RETURNS_INNER_POINTER \
181 __attribute__((__objc_returns_inner_pointer__))
182# define OF_CONSUMED __attribute__((__ns_consumed__))
183# define OF_WEAK_UNAVAILABLE __attribute__((__objc_arc_weak_unavailable__))
184#else
185# define OF_RETURNS_RETAINED
186# define OF_RETURNS_NOT_RETAINED
187# define OF_RETURNS_INNER_POINTER
188# define OF_CONSUMED
189# define OF_WEAK_UNAVAILABLE
190/*
191 * undef them first, as new Clang versions have these as built-in defines even
192 * when ARC is disabled.
193 */
194# undef __unsafe_unretained
195# undef __bridge
196# undef __autoreleasing
197# define __unsafe_unretained
198# define __bridge
199# define __autoreleasing
200#endif
201
202#if __has_feature(objc_generics)
203# define OF_HAVE_GENERICS
204# define OF_GENERIC(...) <__VA_ARGS__>
205#else
206# define OF_GENERIC(...)
207#endif
208
209#if __has_feature(nullability)
210# define OF_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin")
211# define OF_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end")
212# define OF_NULLABLE_PROPERTY(...) (__VA_ARGS__, nullable)
213# define OF_NULL_RESETTABLE_PROPERTY(...) (__VA_ARGS__, null_resettable)
214#else
215# define OF_ASSUME_NONNULL_BEGIN
216# define OF_ASSUME_NONNULL_END
217# define _Nonnull
218# define _Nullable
219# define _Null_unspecified
220# define OF_NULLABLE_PROPERTY
221# define OF_NULL_RESETTABLE_PROPERTY
222# define nonnull
223# define nullable
224# define null_unspecified
225#endif
226
227#if __has_feature(objc_kindof)
228# define OF_KINDOF(class_) __kindof class_
229#else
230# define OF_KINDOF(class_) id
231#endif
232
233#if __has_feature(objc_class_property)
234# define OF_HAVE_CLASS_PROPERTIES
235#endif
236
237#if defined(__clang__) || OF_GCC_VERSION >= 405
238# define OF_UNREACHABLE __builtin_unreachable();
239#else
240# define OF_UNREACHABLE abort();
241#endif
242
243#if defined(__clang__) || OF_GCC_VERSION >= 406
244# define OF_SENTINEL __attribute__((__sentinel__))
245# define OF_NO_RETURN __attribute__((__noreturn__))
246#else
247# define OF_SENTINEL
248# define OF_NO_RETURN
249#endif
250
251#ifdef __clang__
252# define OF_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
253#else
254# define OF_WARN_UNUSED_RESULT
255#endif
256
257#if __has_attribute(__unavailable__)
258# define OF_UNAVAILABLE __attribute__((__unavailable__))
259#else
260# define OF_UNAVAILABLE
261#endif
262
263#if __has_attribute(__objc_requires_super__)
264# define OF_REQUIRES_SUPER __attribute__((__objc_requires_super__))
265#else
266# define OF_REQUIRES_SUPER
267#endif
268
269#if __has_attribute(__objc_root_class__)
270# define OF_ROOT_CLASS __attribute__((__objc_root_class__))
271#else
272# define OF_ROOT_CLASS
273#endif
274
275#if __has_attribute(__objc_subclassing_restricted__)
276# define OF_SUBCLASSING_RESTRICTED \
277 __attribute__((__objc_subclassing_restricted__))
278#else
279# define OF_SUBCLASSING_RESTRICTED
280#endif
281
282#if __has_attribute(__objc_method_family__)
283# define OF_METHOD_FAMILY(f) __attribute__((__objc_method_family__(f)))
284#else
285# define OF_METHOD_FAMILY(f)
286#endif
287
288#if __has_attribute(__objc_designated_initializer__)
289# define OF_DESIGNATED_INITIALIZER \
290 __attribute__((__objc_designated_initializer__))
291#else
292# define OF_DESIGNATED_INITIALIZER
293#endif
294
295#if __has_attribute(__objc_boxable__)
296# define OF_BOXABLE __attribute__((__objc_boxable__))
297#else
298# define OF_BOXABLE
299#endif
300
301#if __has_attribute(__swift_name__)
302# define OF_SWIFT_NAME(name) __attribute__((__swift_name__(name)))
303#else
304# define OF_SWIFT_NAME(name)
305#endif
306
307#if __has_attribute(__objc_direct__) && defined(OF_APPLE_RUNTIME)
308# define OF_DIRECT __attribute__((__objc_direct__))
309#else
310# define OF_DIRECT
311#endif
312#if __has_attribute(__objc_direct_members__) && defined(OF_APPLE_RUNTIME)
313# define OF_DIRECT_MEMBERS __attribute__((__objc_direct_members__))
314#else
315# define OF_DIRECT_MEMBERS
316#endif
317
318#ifdef OF_APPLE_RUNTIME
319# if defined(OF_AMD64) || defined(OF_X86) || defined(OF_ARM64) || \
320 defined(OF_ARM) || defined(OF_POWERPC)
321# define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR
322# define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET
323# endif
324#else
325# if defined(OF_ELF)
326# if defined(OF_AMD64) || defined(OF_X86) || \
327 defined(OF_ARM64) || defined(OF_ARM) || defined(OF_POWERPC) || \
328 defined(OF_MIPS) || defined(OF_SPARC64) || defined(OF_SPARC)
329# define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR
330# if __OBJFW_RUNTIME_ABI__ >= 800
331# define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET
332# endif
333# endif
334# elif defined(OF_MACH_O)
335# if defined(OF_AMD64)
336# define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR
337# if __OBJFW_RUNTIME_ABI__ >= 800
338# define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET
339# endif
340# endif
341# elif defined(OF_WINDOWS)
342# if defined(OF_AMD64) || defined(OF_X86)
343# define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR
344# if __OBJFW_RUNTIME_ABI__ >= 800
345# define OF_HAVE_FORWARDING_TARGET_FOR_SELECTOR_STRET
346# endif
347# endif
348# endif
349#endif
350
351#define OFMaxRetainCount UINT_MAX
352
353#ifdef OBJC_COMPILING_RUNTIME
354# define OFEnsure(cond) \
355 do { \
356 if OF_UNLIKELY (!(cond)) \
357 objc_error("ObjFWRT @ " __FILE__ ":" \
358 OF_STRINGIFY(__LINE__), \
359 "Failed to ensure condition:\n" #cond); \
360 } while(0)
361#else
362@class OFConstantString;
363# ifdef __cplusplus
364extern "C" {
365# endif
366extern void OFLog(OFConstantString *_Nonnull, ...);
367# ifdef __cplusplus
368}
369# endif
370# define OFEnsure(cond) \
371 do { \
372 if OF_UNLIKELY (!(cond)) { \
373 OFLog(@"Failed to ensure condition in " \
374 @__FILE__ ":%d: " @#cond, __LINE__); \
375 abort(); \
376 } \
377 } while (0)
378#endif
379
380#ifndef NDEBUG
381# define OFAssert(...) OFEnsure(__VA_ARGS__)
382#else
383# define OFAssert(...)
384#endif
385
386#define OF_UNRECOGNIZED_SELECTOR OFMethodNotFound(self, _cmd);
387#if __has_feature(objc_arc)
388# define OF_INVALID_INIT_METHOD OFMethodNotFound(self, _cmd);
389#else
390# define OF_INVALID_INIT_METHOD \
391 @try { \
392 OFMethodNotFound(self, _cmd); \
393 } @catch (id e) { \
394 [self release]; \
395 @throw e; \
396 } \
397 \
398 abort();
399#endif
400#ifdef __clang__
401# define OF_DEALLOC_UNSUPPORTED \
402 [self doesNotRecognizeSelector: _cmd]; \
403 \
404 abort(); \
405 \
406 _Pragma("clang diagnostic push"); \
407 _Pragma("clang diagnostic ignored \"-Wunreachable-code\""); \
408 [super dealloc]; /* Get rid of a stupid warning */ \
409 _Pragma("clang diagnostic pop");
410#else
411# define OF_DEALLOC_UNSUPPORTED \
412 [self doesNotRecognizeSelector: _cmd]; \
413 \
414 abort(); \
415 \
416 [super dealloc]; /* Get rid of a stupid warning */
417#endif
418#define OF_SINGLETON_METHODS \
419 - (instancetype)autorelease \
420 { \
421 return self; \
422 } \
423 \
424 - (instancetype)retain \
425 { \
426 return self; \
427 } \
428 \
429 - (void)release \
430 { \
431 } \
432 \
433 - (unsigned int)retainCount \
434 { \
435 return OFMaxRetainCount; \
436 } \
437 \
438 - (void)dealloc \
439 { \
440 OF_DEALLOC_UNSUPPORTED \
441 }
442
443#define OF_CONSTRUCTOR(prio) \
444 static void __attribute__((__constructor__(prio))) \
445 OF_PREPROCESSOR_CONCAT(constructor, __LINE__)(void)
446#define OF_DESTRUCTOR(prio) \
447 static void __attribute__((__destructor__(prio))) \
448 OF_PREPROCESSOR_CONCAT(destructor, __LINE__)(void)
449
450static OF_INLINE uint16_t OF_CONST_FUNC
451OFByteSwap16Const(uint16_t i)
452{
453 return (i & UINT16_C(0xFF00)) >> 8 | (i & UINT16_C(0x00FF)) << 8;
454}
455
456static OF_INLINE uint32_t OF_CONST_FUNC
457OFByteSwap32Const(uint32_t i)
458{
459 return (i & UINT32_C(0xFF000000)) >> 24 |
460 (i & UINT32_C(0x00FF0000)) >> 8 |
461 (i & UINT32_C(0x0000FF00)) << 8 |
462 (i & UINT32_C(0x000000FF)) << 24;
463}
464
465static OF_INLINE uint64_t OF_CONST_FUNC
466OFByteSwap64Const(uint64_t i)
467{
468 return (i & UINT64_C(0xFF00000000000000)) >> 56 |
469 (i & UINT64_C(0x00FF000000000000)) >> 40 |
470 (i & UINT64_C(0x0000FF0000000000)) >> 24 |
471 (i & UINT64_C(0x000000FF00000000)) >> 8 |
472 (i & UINT64_C(0x00000000FF000000)) << 8 |
473 (i & UINT64_C(0x0000000000FF0000)) << 24 |
474 (i & UINT64_C(0x000000000000FF00)) << 40 |
475 (i & UINT64_C(0x00000000000000FF)) << 56;
476}
477
478static OF_INLINE uint16_t OF_CONST_FUNC
479OFByteSwap16NonConst(uint16_t i)
480{
481#if defined(OF_HAVE_BUILTIN_BSWAP16)
482 return __builtin_bswap16(i);
483#elif (defined(OF_AMD64) || defined(OF_X86)) && defined(__GNUC__)
484 __asm__ (
485 "xchgb %h0, %b0"
486 : "=Q"(i)
487 : "0"(i)
488 );
489#elif defined(OF_POWERPC) && defined(__GNUC__)
490 __asm__ (
491 "lhbrx %0, 0, %1"
492 : "=r"(i)
493 : "r"(&i), "m"(i)
494 );
495#elif defined(OF_ARMV6) && defined(__GNUC__)
496 __asm__ (
497 "rev16 %0, %0"
498 : "=r"(i)
499 : "0"(i)
500 );
501#else
502 i = (i & UINT16_C(0xFF00)) >> 8 |
503 (i & UINT16_C(0x00FF)) << 8;
504#endif
505 return i;
506}
507
508static OF_INLINE uint32_t OF_CONST_FUNC
509OFByteSwap32NonConst(uint32_t i)
510{
511#if defined(OF_HAVE_BUILTIN_BSWAP32)
512 return __builtin_bswap32(i);
513#elif (defined(OF_AMD64) || defined(OF_X86)) && defined(__GNUC__)
514 __asm__ (
515 "bswap %0"
516 : "=q"(i)
517 : "0"(i)
518 );
519#elif defined(OF_POWERPC) && defined(__GNUC__)
520 __asm__ (
521 "lwbrx %0, 0, %1"
522 : "=r"(i)
523 : "r"(&i), "m"(i)
524 );
525#elif defined(OF_ARMV6) && defined(__GNUC__)
526 __asm__ (
527 "rev %0, %0"
528 : "=r"(i)
529 : "0"(i)
530 );
531#else
532 i = (i & UINT32_C(0xFF000000)) >> 24 |
533 (i & UINT32_C(0x00FF0000)) >> 8 |
534 (i & UINT32_C(0x0000FF00)) << 8 |
535 (i & UINT32_C(0x000000FF)) << 24;
536#endif
537 return i;
538}
539
540static OF_INLINE uint64_t OF_CONST_FUNC
541OFByteSwap64NonConst(uint64_t i)
542{
543#if defined(OF_HAVE_BUILTIN_BSWAP64)
544 return __builtin_bswap64(i);
545#elif defined(OF_AMD64) && defined(__GNUC__)
546 __asm__ (
547 "bswap %0"
548 : "=r"(i)
549 : "0"(i)
550 );
551#elif defined(OF_X86) && defined(__GNUC__)
552 __asm__ (
553 "bswap %%eax\n\t"
554 "bswap %%edx\n\t"
555 "xchgl %%eax, %%edx"
556 : "=A"(i)
557 : "0"(i)
558 );
559#else
560 i = (uint64_t)OFByteSwap32NonConst(
561 (uint32_t)(i & UINT32_C(0xFFFFFFFF))) << 32 |
562 OFByteSwap32NonConst((uint32_t)(i >> 32));
563#endif
564 return i;
565}
566
567#ifdef __GNUC__
568# define OFByteSwap16(i) \
569 (__builtin_constant_p(i) ? OFByteSwap16Const(i) : OFByteSwap16NonConst(i))
570# define OFByteSwap32(i) \
571 (__builtin_constant_p(i) ? OFByteSwap32Const(i) : OFByteSwap32NonConst(i))
572# define OFByteSwap64(i) \
573 (__builtin_constant_p(i) ? OFByteSwap64Const(i) : OFByteSwap64NonConst(i))
574#else
575# define OFByteSwap16(i) OFByteSwap16Const(i)
576# define OFByteSwap32(i) OFByteSwap32Const(i)
577# define OFByteSwap64(i) OFByteSwap64Const(i)
578#endif
579
580static OF_INLINE uint32_t
581OFFloatToRawUInt32(float f)
582{
583 uint32_t ret;
584 memcpy(&ret, &f, 4);
585 return ret;
586}
587
588static OF_INLINE float
589OFRawUInt32ToFloat(uint32_t uInt32)
590{
591 float ret;
592 memcpy(&ret, &uInt32, 4);
593 return ret;
594}
595
596static OF_INLINE uint64_t
597OFDoubleToRawUInt64(double d)
598{
599 uint64_t ret;
600 memcpy(&ret, &d, 8);
601 return ret;
602}
603
604static OF_INLINE double
605OFRawUInt64ToDouble(uint64_t uInt64)
606{
607 double ret;
608 memcpy(&ret, &uInt64, 8);
609 return ret;
610}
611
612static OF_INLINE float OF_CONST_FUNC
613OFByteSwapFloat(float f)
614{
615 return OFRawUInt32ToFloat(OFByteSwap32(OFFloatToRawUInt32(f)));
616}
617
618static OF_INLINE double OF_CONST_FUNC
619OFByteSwapDouble(double d)
620{
621 return OFRawUInt64ToDouble(OFByteSwap64(OFDoubleToRawUInt64(d)));
622}
623
624#ifdef OF_BIG_ENDIAN
625# define OFFromBigEndian16(i) (i)
626# define OFFromBigEndian32(i) (i)
627# define OFFromBigEndian64(i) (i)
628# define OFFromLittleEndian16(i) OFByteSwap16(i)
629# define OFFromLittleEndian32(i) OFByteSwap32(i)
630# define OFFromLittleEndian64(i) OFByteSwap64(i)
631# define OFToBigEndian16(i) (i)
632# define OFToBigEndian32(i) (i)
633# define OFToBigEndian64(i) (i)
634# define OFToLittleEndian16(i) OFByteSwap16(i)
635# define OFToLittleEndian32(i) OFByteSwap32(i)
636# define OFToLittleEndian64(i) OFByteSwap64(i)
637#else
638# define OFFromBigEndian16(i) OFByteSwap16(i)
639# define OFFromBigEndian32(i) OFByteSwap32(i)
640# define OFFromBigEndian64(i) OFByteSwap64(i)
641# define OFFromLittleEndian16(i) (i)
642# define OFFromLittleEndian32(i) (i)
643# define OFFromLittleEndian64(i) (i)
644# define OFToBigEndian16(i) OFByteSwap16(i)
645# define OFToBigEndian32(i) OFByteSwap32(i)
646# define OFToBigEndian64(i) OFByteSwap64(i)
647# define OFToLittleEndian16(i) (i)
648# define OFToLittleEndian32(i) (i)
649# define OFToLittleEndian64(i) (i)
650#endif
651
652#ifdef OF_FLOAT_BIG_ENDIAN
653# define OFFromBigEndianFloat(f) (f)
654# define OFFromBigEndianDouble(d) (d)
655# define OFFromLittleEndianFloat(f) OFByteSwapFloat(f)
656# define OFFromLittleEndianDouble(d) OFByteSwapDouble(d)
657# define OFToBigEndianFloat(f) (f)
658# define OFToBigEndianDouble(d) (d)
659# define OFToLittleEndianFloat(f) OFByteSwapFloat(f)
660# define OFToLittleEndianDouble(d) OFByteSwapDouble(d)
661#else
662# define OFFromBigEndianFloat(f) OFByteSwapFloat(f)
663# define OFFromBigEndianDouble(d) OFByteSwapDouble(d)
664# define OFFromLittleEndianFloat(f) (f)
665# define OFFromLittleEndianDouble(d) (d)
666# define OFToBigEndianFloat(f) OFByteSwapFloat(f)
667# define OFToBigEndianDouble(d) OFByteSwapDouble(d)
668# define OFToLittleEndianFloat(f) (f)
669# define OFToLittleEndianDouble(d) (d)
670#endif
671
672#define OFRotateLeft(value, bits) \
673 (((bits) % (sizeof(value) * 8)) > 0 \
674 ? ((value) << ((bits) % (sizeof(value) * 8))) | \
675 ((value) >> (sizeof(value) * 8 - ((bits) % (sizeof(value) * 8)))) \
676 : (value))
677#define OFRotateRight(value, bits) \
678 (((bits) % (sizeof(value) * 8)) > 0 \
679 ? ((value) >> ((bits) % (sizeof(value) * 8))) | \
680 ((value) << (sizeof(value) * 8 - ((bits) % (sizeof(value) * 8)))) \
681 : (value))
682
683#define OFRoundUpToPowerOf2(pow2, value) \
684 (((value) + (pow2) - 1) & ~((pow2) - 1))
685
686static OF_INLINE bool
687OFBitsetIsSet(unsigned char *_Nonnull storage, size_t idx)
688{
689 return storage[idx / CHAR_BIT] & (1u << (idx % CHAR_BIT));
690}
691
692static OF_INLINE void
693OFBitsetSet(unsigned char *_Nonnull storage, size_t idx)
694{
695 storage[idx / CHAR_BIT] |= (1u << (idx % CHAR_BIT));
696}
697
698static OF_INLINE void
699OFBitsetClear(unsigned char *_Nonnull storage, size_t idx)
700{
701 storage[idx / CHAR_BIT] &= ~(1u << (idx % CHAR_BIT));
702}
703
704static OF_INLINE void
705OFZeroMemory(void *_Nonnull buffer_, size_t length)
706{
707 volatile unsigned char *buffer = (volatile unsigned char *)buffer_;
708
709 while (buffer < (unsigned char *)buffer_ + length)
710 *buffer++ = '\0';
711}
712
713static OF_INLINE bool
714OFASCIIIsAlpha(char c)
715{
716 return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'));
717}
718
719static OF_INLINE bool
720OFASCIIIsDigit(char c)
721{
722 return (c >= '0' && c <= '9');
723}
724
725static OF_INLINE bool
726OFASCIIIsAlnum(char c)
727{
728 return (OFASCIIIsAlpha(c) || OFASCIIIsDigit(c));
729}
730
731static OF_INLINE bool
732OFASCIIIsSpace(char c)
733{
734 return (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' ||
735 c == '\v');
736}
737
738static OF_INLINE char
739OFASCIIToUpper(char c)
740{
741 return (c >= 'a' && c <= 'z' ? 'A' + (c - 'a') : c);
742}
743
744static OF_INLINE char
745OFASCIIToLower(char c)
746{
747 return (c >= 'A' && c <= 'Z' ? 'a' + (c - 'A') : c);
748}
749#endif
A class for storing constant strings using the @"" literal.
Definition OFConstantString.h:38