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