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 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
42#include "platform.h"
43
44#ifdef OF_OBJFW_RUNTIME
45# ifdef OF_COMPILING_OBJFW
46# include "ObjFWRT.h"
47# else
48# include <ObjFWRT/ObjFWRT.h>
49# endif
50#endif
51#ifdef OF_APPLE_RUNTIME
52# include <objc/objc.h>
53# include <objc/runtime.h>
54# include <objc/message.h>
55#endif
56
57#if defined(__GNUC__)
58# define restrict __restrict__
59#elif __STDC_VERSION__ < 199901L
60# define restrict
61#endif
62
63#if __STDC_VERSION__ >= 201112L && !defined(static_assert)
64/* C11 compiler, but old libc */
65# define static_assert _Static_assert
66#endif
67
68#if defined(OF_HAVE__THREAD_LOCAL)
69# define OF_HAVE_COMPILER_TLS
70# ifdef OF_HAVE_THREADS_H
71# include <threads.h>
72# ifdef OF_AIX
73/* AIX has a bug where thread_local is defined to "Thread_local;". */
74# undef thread_local
75# define thread_local _Thread_local
76# endif
77# else
78# define thread_local _Thread_local
79# endif
80#elif defined(OF_HAVE___THREAD)
81# define OF_HAVE_COMPILER_TLS
82# define thread_local __thread
83#endif
84
85/*
86 * Do not use compiler TLS when targeting the iOS simulator, as the iOS 9
87 * simulator does not support it (fails at runtime).
88 */
89#if defined(OF_HAVE_COMPILER_TLS) && defined(OF_IOS) && defined(OF_X86)
90# undef OF_HAVE_COMPILER_TLS
91#endif
92
93#ifdef __GNUC__
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)))
100#else
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)
107#endif
108
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)
113#else
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))
117#endif
118
119#ifdef __BIGGEST_ALIGNMENT__
120# define OF_BIGGEST_ALIGNMENT __BIGGEST_ALIGNMENT__
121#else
122/* Hopefully no arch needs more than 16 byte alignment */
123# define OF_BIGGEST_ALIGNMENT 16
124#endif
125/*
126 * We use SSE inline assembly on AMD64 and x86, so it must never be smaller
127 * than 16.
128 */
129#if (defined(OF_AMD64) || defined(OF_X86)) && OF_BIGGEST_ALIGNMENT < 16
130# undef OF_BIGGEST_ALIGNMENT
131# define OF_BIGGEST_ALIGNMENT 16
132#endif
133
134#define OF_PREPROCESSOR_CONCAT2(a, b) a##b
135#define OF_PREPROCESSOR_CONCAT(a, b) OF_PREPROCESSOR_CONCAT2(a, b)
136
137#if __OBJFW_RUNTIME_ABI__ || (defined(OF_APPLE_RUNTIME) && defined(__OBJC2__))
138# define OF_HAVE_NONFRAGILE_IVARS
139#endif
140
141#ifdef OF_HAVE_NONFRAGILE_IVARS
142# define OF_RESERVE_IVARS(cls, num)
143#else
144# define OF_RESERVE_IVARS(cls, num) \
145 @private \
146 void *OF_PREPROCESSOR_CONCAT(_reserved_, cls)[num];
147#endif
148
149#ifdef __GNUC__
150# define OF_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
151#else
152# define OF_GCC_VERSION 0
153#endif
154
155#define OF_STRINGIFY(s) OF_STRINGIFY2(s)
156#define OF_STRINGIFY2(s) #s
157
158#ifndef __has_feature
159# define __has_feature(x) 0
160#endif
161
162#ifndef __has_attribute
163# define __has_attribute(x) 0
164#endif
165
166#if __has_feature(objc_bool)
167# undef YES
168# define YES __objc_yes
169# undef NO
170# define NO __objc_no
171# ifndef __cplusplus
172# undef true
173# define true ((bool)1)
174# undef false
175# define false ((bool)0)
176# endif
177#endif
178
179#if !__has_feature(objc_instancetype)
180# define instancetype id
181#endif
182
183#if __has_feature(blocks)
184# define OF_HAVE_BLOCKS
185#endif
186
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__))
194#else
195# define OF_RETURNS_RETAINED
196# define OF_RETURNS_NOT_RETAINED
197# define OF_RETURNS_INNER_POINTER
198# define OF_CONSUMED
199# define OF_WEAK_UNAVAILABLE
200/*
201 * undef them first, as new Clang versions have these as built-in defines even
202 * when ARC is disabled.
203 */
204# undef __unsafe_unretained
205# undef __bridge
206# undef __autoreleasing
207# define __unsafe_unretained
208# define __bridge
209# define __autoreleasing
210#endif
211
212#if __has_feature(objc_generics)
213# define OF_HAVE_GENERICS
214# define OF_GENERIC(...) <__VA_ARGS__>
215#else
216# define OF_GENERIC(...)
217#endif
218
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)
224#else
225# define OF_ASSUME_NONNULL_BEGIN
226# define OF_ASSUME_NONNULL_END
227# define _Nonnull
228# define _Nullable
229# define _Null_unspecified
230# define OF_NULLABLE_PROPERTY
231# define OF_NULL_RESETTABLE_PROPERTY
232# define nonnull
233# define nullable
234# define null_unspecified
235#endif
236
237#if __has_feature(objc_kindof)
238# define OF_KINDOF(class_) __kindof class_
239#else
240# define OF_KINDOF(class_) id
241#endif
242
243#if __has_feature(objc_class_property)
244# define OF_HAVE_CLASS_PROPERTIES
245#endif
246
247#if defined(__clang__) || OF_GCC_VERSION >= 405
248# define OF_UNREACHABLE __builtin_unreachable();
249#else
250# define OF_UNREACHABLE abort();
251#endif
252
253#if defined(__clang__) || OF_GCC_VERSION >= 406
254# define OF_SENTINEL __attribute__((__sentinel__))
255# define OF_NO_RETURN __attribute__((__noreturn__))
256#else
257# define OF_SENTINEL
258# define OF_NO_RETURN
259#endif
260
261#ifdef __clang__
262# define OF_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
263#else
264# define OF_WARN_UNUSED_RESULT
265#endif
266
267#if __has_attribute(__unavailable__)
268# define OF_UNAVAILABLE __attribute__((__unavailable__))
269#else
270# define OF_UNAVAILABLE
271#endif
272
273#if __has_attribute(__objc_requires_super__)
274# define OF_REQUIRES_SUPER __attribute__((__objc_requires_super__))
275#else
276# define OF_REQUIRES_SUPER
277#endif
278
279#if __has_attribute(__objc_root_class__)
280# define OF_ROOT_CLASS __attribute__((__objc_root_class__))
281#else
282# define OF_ROOT_CLASS
283#endif
284
285#if __has_attribute(__objc_subclassing_restricted__)
286# define OF_SUBCLASSING_RESTRICTED \
287 __attribute__((__objc_subclassing_restricted__))
288#else
289# define OF_SUBCLASSING_RESTRICTED
290#endif
291
292#if __has_attribute(__objc_method_family__)
293# define OF_METHOD_FAMILY(f) __attribute__((__objc_method_family__(f)))
294#else
295# define OF_METHOD_FAMILY(f)
296#endif
297
298#if __has_attribute(__objc_designated_initializer__)
299# define OF_DESIGNATED_INITIALIZER \
300 __attribute__((__objc_designated_initializer__))
301#else
302# define OF_DESIGNATED_INITIALIZER
303#endif
304
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__))
312#else
313# define OF_DEPRECATED(project, major, minor, msg)
314#endif
315
316#if __has_attribute(__objc_boxable__)
317# define OF_BOXABLE __attribute__((__objc_boxable__))
318#else
319# define OF_BOXABLE
320#endif
321
322#if __has_attribute(__swift_name__)
323# define OF_SWIFT_NAME(name) __attribute__((__swift_name__(name)))
324#else
325# define OF_SWIFT_NAME(name)
326#endif
327
328#if __has_attribute(__objc_direct__) && defined(OF_APPLE_RUNTIME)
329# define OF_DIRECT __attribute__((__objc_direct__))
330#else
331# define OF_DIRECT
332#endif
333#if __has_attribute(__objc_direct_members__) && defined(OF_APPLE_RUNTIME)
334# define OF_DIRECT_MEMBERS __attribute__((__objc_direct_members__))
335#else
336# define OF_DIRECT_MEMBERS
337#endif
338
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
344# endif
345#else
346# if defined(OF_ELF)
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
353# endif
354# endif
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
360# endif
361# endif
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
367# endif
368# endif
369# endif
370#endif
371
372#define OFMaxRetainCount UINT_MAX
373
374#ifdef OBJC_COMPILING_RUNTIME
375# define OFEnsure(cond) \
376 do { \
377 if OF_UNLIKELY (!(cond)) \
378 objc_error("ObjFWRT @ " __FILE__ ":" \
379 OF_STRINGIFY(__LINE__), \
380 "Failed to ensure condition:\n" #cond); \
381 } while(0)
382#else
383@class OFConstantString;
384# ifdef __cplusplus
385extern "C" {
386# endif
387extern void OFLog(OFConstantString *_Nonnull, ...);
388# ifdef __cplusplus
389}
390# endif
391# define OFEnsure(cond) \
392 do { \
393 if OF_UNLIKELY (!(cond)) { \
394 OFLog(@"Failed to ensure condition in " \
395 @__FILE__ ":%d: " @#cond, __LINE__); \
396 abort(); \
397 } \
398 } while (0)
399#endif
400
401#ifndef NDEBUG
402# define OFAssert(...) OFEnsure(__VA_ARGS__)
403#else
404# define OFAssert(...)
405#endif
406
407#define OF_UNRECOGNIZED_SELECTOR OFMethodNotFound(self, _cmd);
408#if __has_feature(objc_arc)
409# define OF_INVALID_INIT_METHOD OFMethodNotFound(self, _cmd);
410#else
411# define OF_INVALID_INIT_METHOD \
412 @try { \
413 OFMethodNotFound(self, _cmd); \
414 } @catch (id e) { \
415 [self release]; \
416 @throw e; \
417 } \
418 \
419 abort();
420#endif
421#ifdef __clang__
422# define OF_DEALLOC_UNSUPPORTED \
423 [self doesNotRecognizeSelector: _cmd]; \
424 \
425 abort(); \
426 \
427 _Pragma("clang diagnostic push"); \
428 _Pragma("clang diagnostic ignored \"-Wunreachable-code\""); \
429 [super dealloc]; /* Get rid of a stupid warning */ \
430 _Pragma("clang diagnostic pop");
431#else
432# define OF_DEALLOC_UNSUPPORTED \
433 [self doesNotRecognizeSelector: _cmd]; \
434 \
435 abort(); \
436 \
437 [super dealloc]; /* Get rid of a stupid warning */
438#endif
439#define OF_SINGLETON_METHODS \
440 - (instancetype)autorelease \
441 { \
442 return self; \
443 } \
444 \
445 - (instancetype)retain \
446 { \
447 return self; \
448 } \
449 \
450 - (void)release \
451 { \
452 } \
453 \
454 - (unsigned int)retainCount \
455 { \
456 return OFMaxRetainCount; \
457 } \
458 \
459 - (void)dealloc \
460 { \
461 OF_DEALLOC_UNSUPPORTED \
462 }
463
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)
470
471static OF_INLINE uint16_t OF_CONST_FUNC
472OFByteSwap16Const(uint16_t i)
473{
474 return (i & UINT16_C(0xFF00)) >> 8 | (i & UINT16_C(0x00FF)) << 8;
475}
476
477static OF_INLINE uint32_t OF_CONST_FUNC
478OFByteSwap32Const(uint32_t i)
479{
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;
484}
485
486static OF_INLINE uint64_t OF_CONST_FUNC
487OFByteSwap64Const(uint64_t i)
488{
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;
497}
498
499static OF_INLINE uint16_t OF_CONST_FUNC
500OFByteSwap16NonConst(uint16_t i)
501{
502#if defined(OF_HAVE_BUILTIN_BSWAP16)
503 return __builtin_bswap16(i);
504#elif (defined(OF_AMD64) || defined(OF_X86)) && defined(__GNUC__)
505 __asm__ (
506 "xchg{b} { %h0, %b0 | %b0, %h0 }"
507 : "=Q" (i)
508 : "0" (i)
509 );
510#elif defined(OF_POWERPC) && defined(__GNUC__)
511 __asm__ (
512 "lhbrx %0, 0, %1"
513 : "=r" (i)
514 : "r" (&i),
515 "m" (i)
516 );
517#elif defined(OF_ARMV6) && defined(__GNUC__)
518 __asm__ (
519 "rev16 %0, %0"
520 : "=r" (i)
521 : "0" (i)
522 );
523#else
524 i = (i & UINT16_C(0xFF00)) >> 8 |
525 (i & UINT16_C(0x00FF)) << 8;
526#endif
527 return i;
528}
529
530static OF_INLINE uint32_t OF_CONST_FUNC
531OFByteSwap32NonConst(uint32_t i)
532{
533#if defined(OF_HAVE_BUILTIN_BSWAP32)
534 return __builtin_bswap32(i);
535#elif (defined(OF_AMD64) || defined(OF_X86)) && defined(__GNUC__)
536 __asm__ (
537 "bswap %0"
538 : "=q" (i)
539 : "0" (i)
540 );
541#elif defined(OF_POWERPC) && defined(__GNUC__)
542 __asm__ (
543 "lwbrx %0, 0, %1"
544 : "=r" (i)
545 : "r" (&i),
546 "m" (i)
547 );
548#elif defined(OF_ARMV6) && defined(__GNUC__)
549 __asm__ (
550 "rev %0, %0"
551 : "=r" (i)
552 : "0" (i)
553 );
554#else
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;
559#endif
560 return i;
561}
562
563static OF_INLINE uint64_t OF_CONST_FUNC
564OFByteSwap64NonConst(uint64_t i)
565{
566#if defined(OF_HAVE_BUILTIN_BSWAP64)
567 return __builtin_bswap64(i);
568#elif defined(OF_AMD64) && defined(__GNUC__)
569 __asm__ (
570 "bswap %0"
571 : "=r" (i)
572 : "0" (i)
573 );
574#elif defined(OF_X86) && defined(__GNUC__)
575 __asm__ (
576 "bswap {%%}eax\n\t"
577 "bswap {%%}edx\n\t"
578 "xchg{l} { %%eax, %%edx | edx, eax }"
579 : "=A" (i)
580 : "0" (i)
581 );
582#else
583 i = (uint64_t)OFByteSwap32NonConst(
584 (uint32_t)(i & UINT32_C(0xFFFFFFFF))) << 32 |
585 OFByteSwap32NonConst((uint32_t)(i >> 32));
586#endif
587 return i;
588}
589
590#ifdef __GNUC__
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))
597#else
598# define OFByteSwap16(i) OFByteSwap16Const(i)
599# define OFByteSwap32(i) OFByteSwap32Const(i)
600# define OFByteSwap64(i) OFByteSwap64Const(i)
601#endif
602
603static OF_INLINE uint32_t
604OFFloatToRawUInt32(float f)
605{
606 uint32_t ret;
607 memcpy(&ret, &f, 4);
608 return ret;
609}
610
611static OF_INLINE float
612OFRawUInt32ToFloat(uint32_t uInt32)
613{
614 float ret;
615 memcpy(&ret, &uInt32, 4);
616 return ret;
617}
618
619static OF_INLINE uint64_t
620OFDoubleToRawUInt64(double d)
621{
622 uint64_t ret;
623 memcpy(&ret, &d, 8);
624 return ret;
625}
626
627static OF_INLINE double
628OFRawUInt64ToDouble(uint64_t uInt64)
629{
630 double ret;
631 memcpy(&ret, &uInt64, 8);
632 return ret;
633}
634
635static OF_INLINE float OF_CONST_FUNC
636OFByteSwapFloat(float f)
637{
638 return OFRawUInt32ToFloat(OFByteSwap32(OFFloatToRawUInt32(f)));
639}
640
641static OF_INLINE double OF_CONST_FUNC
642OFByteSwapDouble(double d)
643{
644 return OFRawUInt64ToDouble(OFByteSwap64(OFDoubleToRawUInt64(d)));
645}
646
647#ifdef OF_BIG_ENDIAN
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)
660#else
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)
673#endif
674
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)
684#else
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)
693#endif
694
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)))) \
699 : (value))
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)))) \
704 : (value))
705
706#define OFRoundUpToPowerOf2(pow2, value) \
707 (((value) + (pow2) - 1) & ~((pow2) - 1))
708
709static OF_INLINE bool
710OFBitsetIsSet(unsigned char *_Nonnull storage, size_t idx)
711{
712 return storage[idx / CHAR_BIT] & (1u << (idx % CHAR_BIT));
713}
714
715static OF_INLINE void
716OFBitsetSet(unsigned char *_Nonnull storage, size_t idx)
717{
718 storage[idx / CHAR_BIT] |= (1u << (idx % CHAR_BIT));
719}
720
721static OF_INLINE void
722OFBitsetClear(unsigned char *_Nonnull storage, size_t idx)
723{
724 storage[idx / CHAR_BIT] &= ~(1u << (idx % CHAR_BIT));
725}
726
727static OF_INLINE void
728OFZeroMemory(void *_Nonnull buffer_, size_t length)
729{
730 volatile unsigned char *buffer = (volatile unsigned char *)buffer_;
731
732 while (buffer < (unsigned char *)buffer_ + length)
733 *buffer++ = '\0';
734}
735
736static OF_INLINE bool
737OFASCIIIsAlpha(char c)
738{
739 return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'));
740}
741
742static OF_INLINE bool
743OFASCIIIsDigit(char c)
744{
745 return (c >= '0' && c <= '9');
746}
747
748static OF_INLINE bool
749OFASCIIIsAlnum(char c)
750{
751 return (OFASCIIIsAlpha(c) || OFASCIIIsDigit(c));
752}
753
754static OF_INLINE bool
755OFASCIIIsSpace(char c)
756{
757 return (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' ||
758 c == '\v');
759}
760
761static OF_INLINE char
762OFASCIIToUpper(char c)
763{
764 return (c >= 'a' && c <= 'z' ? 'A' + (c - 'a') : c);
765}
766
767static OF_INLINE char
768OFASCIIToLower(char c)
769{
770 return (c >= 'A' && c <= 'Z' ? 'a' + (c - 'A') : c);
771}
772#endif
A class for storing constant strings using the @"" literal.
Definition OFConstantString.h:42