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