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