ObjFW
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
398 extern "C" {
399 # endif
400 extern 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 
484 static 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 
490 static 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 
499 static 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 
512 static 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 
543 static 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 
576 static 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 
642 static OF_INLINE uint32_t OF_CONST_FUNC
644 {
645  uint32_t ret;
646  memcpy(&ret, &f, 4);
647  return ret;
648 }
649 
656 static OF_INLINE float OF_CONST_FUNC
658 {
659  float ret;
660  memcpy(&ret, &uInt32, 4);
661  return ret;
662 }
663 
670 static OF_INLINE uint64_t OF_CONST_FUNC
672 {
673  uint64_t ret;
674  memcpy(&ret, &d, 8);
675  return ret;
676 }
677 
684 static OF_INLINE double OF_CONST_FUNC
686 {
687  double ret;
688  memcpy(&ret, &uInt64, 8);
689  return ret;
690 }
691 
698 static OF_INLINE float OF_CONST_FUNC
700 {
703 }
704 
711 static OF_INLINE double OF_CONST_FUNC
713 {
716 }
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 
954 static OF_INLINE bool
955 OFBitSetIsSet(unsigned long *_Nonnull storage, size_t idx)
956 {
957  return storage[idx / OF_ULONG_BIT] & (1ul << (idx % OF_ULONG_BIT));
958 }
959 
960 static OF_INLINE void
961 OFBitSetSet(unsigned long *_Nonnull storage, size_t idx)
962 {
963  storage[idx / OF_ULONG_BIT] |= (1ul << (idx % OF_ULONG_BIT));
964 }
965 
966 static OF_INLINE void
967 OFBitSetClear(unsigned long *_Nonnull storage, size_t idx)
968 {
969  storage[idx / OF_ULONG_BIT] &= ~(1ul << (idx % OF_ULONG_BIT));
970 }
971 
972 static OF_INLINE void
973 OFZeroMemory(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 
981 static OF_INLINE bool
982 OFASCIIIsAlpha(char c)
983 {
984  return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'));
985 }
986 
987 static OF_INLINE bool
988 OFASCIIIsDigit(char c)
989 {
990  return (c >= '0' && c <= '9');
991 }
992 
993 static OF_INLINE bool
994 OFASCIIIsAlnum(char c)
995 {
996  return (OFASCIIIsAlpha(c) || OFASCIIIsDigit(c));
997 }
998 
999 static OF_INLINE bool
1000 OFASCIIIsSpace(char c)
1001 {
1002  return (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' ||
1003  c == '\v');
1004 }
1005 
1006 static OF_INLINE char
1007 OFASCIIToUpper(char c)
1008 {
1009  return (c >= 'a' && c <= 'z' ? 'A' + (c - 'a') : c);
1010 }
1011 
1012 static OF_INLINE char
1013 OFASCIIToLower(char c)
1014 {
1015  return (c >= 'A' && c <= 'Z' ? 'a' + (c - 'A') : c);
1016 }
1017 #endif
void OFLog(OFConstantString *format,...)
Logs the specified printf-style format to OFStdErr.
Definition: OFStdIOStream.m:115
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