ObjFW
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 
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
412 extern "C" {
413 # endif
414 extern 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 
515 static 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 
546 static 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 
579 static 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 
645 static OF_INLINE uint32_t OF_CONST_FUNC
647 {
648  uint32_t ret;
649  memcpy(&ret, &f, 4);
650  return ret;
651 }
652 
659 static OF_INLINE float OF_CONST_FUNC
661 {
662  float ret;
663  memcpy(&ret, &uInt32, 4);
664  return ret;
665 }
666 
673 static OF_INLINE uint64_t OF_CONST_FUNC
675 {
676  uint64_t ret;
677  memcpy(&ret, &d, 8);
678  return ret;
679 }
680 
687 static OF_INLINE double OF_CONST_FUNC
689 {
690  double ret;
691  memcpy(&ret, &uInt64, 8);
692  return ret;
693 }
694 
701 static OF_INLINE float OF_CONST_FUNC
703 {
706 }
707 
714 static OF_INLINE double OF_CONST_FUNC
716 {
719 }
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 
963 static OF_INLINE OFFloat16
964 OFFloat16FromFloat(float value)
965 {
966  return value;
967 }
968 
969 static OF_INLINE float
970 OFFloat16ToFloat(OFFloat16 value)
971 {
972  return value;
973 }
974 #else
975 typedef uint16_t OFFloat16;
976 
977 static OF_INLINE OFFloat16
978 OFFloat16FromFloat(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 
1003 static OF_INLINE float
1004 OFFloat16ToFloat(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 
1029 static OF_INLINE bool
1030 OFBitSetIsSet(unsigned long *_Nonnull storage, size_t idx)
1031 {
1032  return storage[idx / OF_ULONG_BIT] & (1ul << (idx % OF_ULONG_BIT));
1033 }
1034 
1035 static OF_INLINE void
1036 OFBitSetSet(unsigned long *_Nonnull storage, size_t idx)
1037 {
1038  storage[idx / OF_ULONG_BIT] |= (1ul << (idx % OF_ULONG_BIT));
1039 }
1040 
1041 static OF_INLINE void
1042 OFBitSetClear(unsigned long *_Nonnull storage, size_t idx)
1043 {
1044  storage[idx / OF_ULONG_BIT] &= ~(1ul << (idx % OF_ULONG_BIT));
1045 }
1046 
1047 static OF_INLINE void
1048 OFZeroMemory(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 
1056 static OF_INLINE bool
1057 OFASCIIIsAlpha(char c)
1058 {
1059  return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'));
1060 }
1061 
1062 static OF_INLINE bool
1063 OFASCIIIsDigit(char c)
1064 {
1065  return (c >= '0' && c <= '9');
1066 }
1067 
1068 static OF_INLINE bool
1069 OFASCIIIsAlnum(char c)
1070 {
1071  return (OFASCIIIsAlpha(c) || OFASCIIIsDigit(c));
1072 }
1073 
1074 static OF_INLINE bool
1075 OFASCIIIsSpace(char c)
1076 {
1077  return (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' ||
1078  c == '\v');
1079 }
1080 
1081 static OF_INLINE char
1082 OFASCIIToUpper(char c)
1083 {
1084  return (c >= 'a' && c <= 'z' ? 'A' + (c - 'a') : c);
1085 }
1086 
1087 static OF_INLINE char
1088 OFASCIIToLower(char c)
1089 {
1090  return (c >= 'A' && c <= 'Z' ? 'a' + (c - 'A') : c);
1091 }
1092 #endif
void OFLog(OFConstantString *format,...)
Logs the specified printf-style format to OFStdErr.
Definition: OFStdIOStream.m:118
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