ObjFW
OFObject.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 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 #include "objfw-defs.h"
17 
18 #ifndef __STDC_LIMIT_MACROS
19 # define __STDC_LIMIT_MACROS
20 #endif
21 #ifndef __STDC_CONSTANT_MACROS
22 # define __STDC_CONSTANT_MACROS
23 #endif
24 
25 #include <stddef.h>
26 #include <stdint.h>
27 #include <stdbool.h>
28 #include <limits.h>
29 
30 #include "macros.h"
31 
32 #import "OFOnce.h"
33 
34 /*
35  * Some versions of MinGW require <winsock2.h> to be included before
36  * <windows.h>. Do this here to make sure this is always done in the correct
37  * order, even if another header includes just <windows.h>.
38  */
39 #ifdef __MINGW32__
40 # include <_mingw.h>
41 # ifdef __MINGW64_VERSION_MAJOR
42 # include <winsock2.h>
43 # include <windows.h>
44 # endif
45 #endif
46 
47 OF_ASSUME_NONNULL_BEGIN
48 
54 typedef enum {
62 
71 typedef OFComparisonResult (*OFCompareFunction)(id _Nonnull left,
72  id _Nonnull right, void *_Nullable context);
73 
74 #ifdef OF_HAVE_BLOCKS
75 
82 typedef OFComparisonResult (^OFComparator)(id _Nonnull left, id _Nonnull right);
83 #endif
84 
88 typedef enum {
94 #ifdef OF_BIG_ENDIAN
96 #else
98 #endif
99 } OFByteOrder;
100 
106 typedef struct OF_BOXABLE OFRange {
108  size_t location;
110  size_t length;
111 } OFRange;
112 
120 static OF_INLINE OFRange OF_CONST_FUNC
121 OFMakeRange(size_t start, size_t length)
122 {
123  OFRange range = { start, length };
124 
125  return range;
126 }
127 
135 static OF_INLINE bool
136 OFEqualRanges(OFRange range1, OFRange range2)
137 {
138  if (range1.location != range2.location)
139  return false;
140 
141  if (range1.length != range2.length)
142  return false;
143 
144  return true;
145 }
146 
150 typedef double OFTimeInterval;
151 
157 typedef struct OF_BOXABLE OFPoint {
159  float x;
161  float y;
162 } OFPoint;
163 
171 static OF_INLINE OFPoint OF_CONST_FUNC
172 OFMakePoint(float x, float y)
173 {
174  OFPoint point = { x, y };
175 
176  return point;
177 }
178 
186 static OF_INLINE bool
187 OFEqualPoints(OFPoint point1, OFPoint point2)
188 {
189  if (point1.x != point2.x)
190  return false;
191 
192  if (point1.y != point2.y)
193  return false;
194 
195  return true;
196 }
197 
203 typedef struct OF_BOXABLE OFSize {
205  float width;
207  float height;
208 } OFSize;
209 
217 static OF_INLINE OFSize OF_CONST_FUNC
218 OFMakeSize(float width, float height)
219 {
220  OFSize size = { width, height };
221 
222  return size;
223 }
224 
232 static OF_INLINE bool
233 OFEqualSizes(OFSize size1, OFSize size2)
234 {
235  if (size1.width != size2.width)
236  return false;
237 
238  if (size1.height != size2.height)
239  return false;
240 
241  return true;
242 }
243 
249 typedef struct OF_BOXABLE OFRect {
254 } OFRect;
255 
265 static OF_INLINE OFRect OF_CONST_FUNC
266 OFMakeRect(float x, float y, float width, float height)
267 {
268  OFRect rect = {
269  OFMakePoint(x, y),
270  OFMakeSize(width, height)
271  };
272 
273  return rect;
274 }
275 
283 static OF_INLINE bool
284 OFEqualRects(OFRect rect1, OFRect rect2)
285 {
286  if (!OFEqualPoints(rect1.origin, rect2.origin))
287  return false;
288 
289  if (!OFEqualSizes(rect1.size, rect2.size))
290  return false;
291 
292  return true;
293 }
294 
300 typedef struct OF_BOXABLE OFVector3D {
302  float x;
304  float y;
306  float z;
307 } OFVector3D;
308 
317 static OF_INLINE OFVector3D OF_CONST_FUNC
318 OFMakeVector3D(float x, float y, float z)
319 {
320  OFVector3D vector = { x, y, z };
321 
322  return vector;
323 }
324 
332 static OF_INLINE bool
333 OFEqualVectors3D(OFVector3D vector1, OFVector3D vector2)
334 {
335  if (vector1.x != vector2.x)
336  return false;
337 
338  if (vector1.y != vector2.y)
339  return false;
340 
341  if (vector1.z != vector2.z)
342  return false;
343 
344  return true;
345 }
346 
352 typedef struct OF_BOXABLE OFVector4D {
354  float x;
356  float y;
358  float z;
360  float w;
361 } OFVector4D;
362 
372 static OF_INLINE OFVector4D OF_CONST_FUNC
373 OFMakeVector4D(float x, float y, float z, float w)
374 {
375  OFVector4D vector = { x, y, z, w };
376 
377  return vector;
378 }
379 
387 static OF_INLINE bool
388 OFEqualVectors4D(OFVector4D vector1, OFVector4D vector2)
389 {
390  if (vector1.x != vector2.x)
391  return false;
392 
393  if (vector1.y != vector2.y)
394  return false;
395 
396  if (vector1.z != vector2.z)
397  return false;
398 
399  if (vector1.w != vector2.w)
400  return false;
401 
402  return true;
403 }
404 
411 static OF_INLINE void
412 OFHashAddByte(unsigned long *_Nonnull hash, unsigned char byte)
413 {
414  uint32_t tmp = (uint32_t)*hash;
415 
416  tmp += byte;
417  tmp += tmp << 10;
418  tmp ^= tmp >> 6;
419 
420  *hash = tmp;
421 }
422 
429 static OF_INLINE void
430 OFHashAddHash(unsigned long *_Nonnull hash, unsigned long otherHash)
431 {
432  OFHashAddByte(hash, (otherHash >> 24) & 0xFF);
433  OFHashAddByte(hash, (otherHash >> 16) & 0xFF);
434  OFHashAddByte(hash, (otherHash >> 8) & 0xFF);
435  OFHashAddByte(hash, otherHash & 0xFF);
436 }
437 
443 static OF_INLINE void
444 OFHashFinalize(unsigned long *_Nonnull hash)
445 {
446  uint32_t tmp = (uint32_t)*hash;
447 
448  tmp += tmp << 3;
449  tmp ^= tmp >> 11;
450  tmp += tmp << 15;
451 
452  *hash = tmp;
453 }
454 
455 static const size_t OFNotFound = SIZE_MAX;
456 
457 @class OFMethodSignature;
458 @class OFString;
459 @class OFThread;
460 
466 @protocol OFObject
472 - (Class)class;
473 
479 - (nullable Class)superclass;
480 
493 - (unsigned long)hash;
494 
500 - (unsigned int)retainCount;
501 
507 - (bool)isProxy;
508 
515 - (bool)isKindOfClass: (Class)class_;
516 
524 - (bool)isMemberOfClass: (Class)class_;
525 
533 - (bool)respondsToSelector: (SEL)selector;
534 
541 - (bool)conformsToProtocol: (Protocol *)protocol;
542 
549 - (nullable IMP)methodForSelector: (SEL)selector;
550 
557 - (nullable id)performSelector: (SEL)selector;
558 
567 - (nullable id)performSelector: (SEL)selector withObject: (nullable id)object;
568 
579 - (nullable id)performSelector: (SEL)selector
580  withObject: (nullable id)object1
581  withObject: (nullable id)object2;
582 
595 - (nullable id)performSelector: (SEL)selector
596  withObject: (nullable id)object1
597  withObject: (nullable id)object2
598  withObject: (nullable id)object3;
599 
614 - (nullable id)performSelector: (SEL)selector
615  withObject: (nullable id)object1
616  withObject: (nullable id)object2
617  withObject: (nullable id)object3
618  withObject: (nullable id)object4;
619 
632 - (bool)isEqual: (nullable id)object;
633 
640 - (instancetype)retain;
641 
648 - (void)release;
649 
656 - (instancetype)autorelease;
657 
663 - (instancetype)self;
664 
670 - (bool)allowsWeakReference;
671 
677 - (bool)retainWeakReference;
678 @end
679 
685 OF_ROOT_CLASS
686 @interface OFObject <OFObject>
687 {
688 @private
689 #ifndef __clang_analyzer__
690  Class _isa;
691 #else
692  Class _isa __attribute__((__unused__));
693 #endif
694 }
695 
696 #ifdef OF_HAVE_CLASS_PROPERTIES
697 # ifndef __cplusplus
698 @property (class, readonly, nonatomic) Class class;
699 # else
700 @property (class, readonly, nonatomic, getter=class) Class class_;
701 # endif
702 @property (class, readonly, nonatomic) OFString *className;
703 @property (class, readonly, nullable, nonatomic) Class superclass;
704 @property (class, readonly, nonatomic) OFString *description;
705 #endif
706 
707 #ifndef __cplusplus
708 @property (readonly, nonatomic) Class class;
709 #else
710 @property (readonly, nonatomic, getter=class) Class class_;
711 #endif
712 @property OF_NULLABLE_PROPERTY (readonly, nonatomic) Class superclass;
713 @property (readonly, nonatomic) unsigned long hash;
714 @property (readonly, nonatomic) unsigned int retainCount;
715 @property (readonly, nonatomic) bool isProxy;
716 @property (readonly, nonatomic) bool allowsWeakReference;
717 
721 @property (readonly, nonatomic) OFString *className;
729 @property (readonly, nonatomic) OFString *description;
738 + (void)load;
739 
751 + (void)unload;
752 
762 + (void)initialize;
763 
775 + (instancetype)alloc;
776 
782 + (Class)class;
783 
789 + (OFString *)className;
790 
798 + (bool)isSubclassOfClass: (Class)class_;
799 
805 + (nullable Class)superclass;
806 
814 + (bool)instancesRespondToSelector: (SEL)selector;
815 
822 + (bool)conformsToProtocol: (Protocol *)protocol;
823 
832 + (nullable IMP)instanceMethodForSelector: (SEL)selector;
833 
843 + (nullable OFMethodSignature *)
844  instanceMethodSignatureForSelector: (SEL)selector;
845 
853 + (OFString *)description;
854 
862 + (nullable IMP)replaceClassMethod: (SEL)selector
863  withMethodFromClass: (Class)class_;
864 
873 + (nullable IMP)replaceInstanceMethod: (SEL)selector
874  withMethodFromClass: (Class)class_;
875 
894 + (void)inheritMethodsFromClass: (Class)class_;
895 
904 + (bool)resolveClassMethod: (SEL)selector;
905 
914 + (bool)resolveInstanceMethod: (SEL)selector;
915 
924 + (id)copy;
925 
957 - (instancetype)init;
958 
966 - (nullable OFMethodSignature *)methodSignatureForSelector: (SEL)selector;
967 
975 - (void)dealloc;
976 
983 - (void)performSelector: (SEL)selector afterDelay: (OFTimeInterval)delay;
984 
994 - (void)performSelector: (SEL)selector
995  withObject: (nullable id)object
996  afterDelay: (OFTimeInterval)delay;
997 
1009 - (void)performSelector: (SEL)selector
1010  withObject: (nullable id)object1
1011  withObject: (nullable id)object2
1012  afterDelay: (OFTimeInterval)delay;
1013 
1027 - (void)performSelector: (SEL)selector
1028  withObject: (nullable id)object1
1029  withObject: (nullable id)object2
1030  withObject: (nullable id)object3
1031  afterDelay: (OFTimeInterval)delay;
1032 
1048 - (void)performSelector: (SEL)selector
1049  withObject: (nullable id)object1
1050  withObject: (nullable id)object2
1051  withObject: (nullable id)object3
1052  withObject: (nullable id)object4
1053  afterDelay: (OFTimeInterval)delay;
1054 
1055 #ifdef OF_HAVE_THREADS
1056 
1063 - (void)performSelector: (SEL)selector
1064  onThread: (OFThread *)thread
1065  waitUntilDone: (bool)waitUntilDone;
1066 
1077 - (void)performSelector: (SEL)selector
1078  onThread: (OFThread *)thread
1079  withObject: (nullable id)object
1080  waitUntilDone: (bool)waitUntilDone;
1081 
1094 - (void)performSelector: (SEL)selector
1095  onThread: (OFThread *)thread
1096  withObject: (nullable id)object1
1097  withObject: (nullable id)object2
1098  waitUntilDone: (bool)waitUntilDone;
1099 
1114 - (void)performSelector: (SEL)selector
1115  onThread: (OFThread *)thread
1116  withObject: (nullable id)object1
1117  withObject: (nullable id)object2
1118  withObject: (nullable id)object3
1119  waitUntilDone: (bool)waitUntilDone;
1120 
1137 - (void)performSelector: (SEL)selector
1138  onThread: (OFThread *)thread
1139  withObject: (nullable id)object1
1140  withObject: (nullable id)object2
1141  withObject: (nullable id)object3
1142  withObject: (nullable id)object4
1143  waitUntilDone: (bool)waitUntilDone;
1144 
1151 - (void)performSelectorOnMainThread: (SEL)selector
1152  waitUntilDone: (bool)waitUntilDone;
1153 
1163 - (void)performSelectorOnMainThread: (SEL)selector
1164  withObject: (nullable id)object
1165  waitUntilDone: (bool)waitUntilDone;
1166 
1178 - (void)performSelectorOnMainThread: (SEL)selector
1179  withObject: (nullable id)object1
1180  withObject: (nullable id)object2
1181  waitUntilDone: (bool)waitUntilDone;
1182 
1196 - (void)performSelectorOnMainThread: (SEL)selector
1197  withObject: (nullable id)object1
1198  withObject: (nullable id)object2
1199  withObject: (nullable id)object3
1200  waitUntilDone: (bool)waitUntilDone;
1201 
1217 - (void)performSelectorOnMainThread: (SEL)selector
1218  withObject: (nullable id)object1
1219  withObject: (nullable id)object2
1220  withObject: (nullable id)object3
1221  withObject: (nullable id)object4
1222  waitUntilDone: (bool)waitUntilDone;
1223 
1232 - (void)performSelector: (SEL)selector
1233  onThread: (OFThread *)thread
1234  afterDelay: (OFTimeInterval)delay;
1235 
1246 - (void)performSelector: (SEL)selector
1247  onThread: (OFThread *)thread
1248  withObject: (nullable id)object
1249  afterDelay: (OFTimeInterval)delay;
1250 
1263 - (void)performSelector: (SEL)selector
1264  onThread: (OFThread *)thread
1265  withObject: (nullable id)object1
1266  withObject: (nullable id)object2
1267  afterDelay: (OFTimeInterval)delay;
1268 
1283 - (void)performSelector: (SEL)selector
1284  onThread: (OFThread *)thread
1285  withObject: (nullable id)object1
1286  withObject: (nullable id)object2
1287  withObject: (nullable id)object3
1288  afterDelay: (OFTimeInterval)delay;
1289 
1306 - (void)performSelector: (SEL)selector
1307  onThread: (OFThread *)thread
1308  withObject: (nullable id)object1
1309  withObject: (nullable id)object2
1310  withObject: (nullable id)object3
1311  withObject: (nullable id)object4
1312  afterDelay: (OFTimeInterval)delay;
1313 #endif
1314 
1326 - (nullable id)forwardingTargetForSelector: (SEL)selector;
1327 
1337 - (void)doesNotRecognizeSelector: (SEL)selector OF_NO_RETURN;
1338 @end
1339 
1345 @protocol OFCopying
1355 - (id)copy;
1356 @end
1357 
1366 @protocol OFMutableCopying
1372 - (id)mutableCopy;
1373 @end
1374 
1383 @protocol OFComparing
1390 - (OFComparisonResult)compare: (id <OFComparing>)object;
1391 @end
1392 
1393 #ifdef __cplusplus
1394 extern "C" {
1395 #endif
1396 
1410 extern void *_Nullable OFAllocMemory(size_t count, size_t size)
1411  OF_WARN_UNUSED_RESULT;
1412 
1427 extern void *_Nullable OFAllocZeroedMemory(size_t count, size_t size)
1428  OF_WARN_UNUSED_RESULT;
1429 
1447 extern void *_Nullable OFResizeMemory(void *_Nullable pointer, size_t count,
1448  size_t size) OF_WARN_UNUSED_RESULT;
1449 
1457 extern void OFFreeMemory(void *_Nullable pointer);
1458 
1459 #ifdef OF_APPLE_RUNTIME
1460 extern void *_Null_unspecified objc_autoreleasePoolPush(void);
1461 extern void objc_autoreleasePoolPop(void *_Null_unspecified pool);
1462 # ifndef __OBJC2__
1463 extern id _Nullable objc_constructInstance(Class _Nullable class_,
1464  void *_Nullable bytes);
1465 extern void *_Nullable objc_destructInstance(id _Nullable object);
1466 # endif
1467 #endif
1468 extern id OFAllocObject(Class class_, size_t extraSize, size_t extraAlignment,
1469  void *_Nullable *_Nullable extra);
1470 extern void OF_NO_RETURN_FUNC OFMethodNotFound(id self, SEL _cmd);
1471 
1477 extern void OFHashInit(unsigned long *_Nonnull hash);
1478 
1484 extern uint16_t OFRandom16(void);
1485 
1491 extern uint32_t OFRandom32(void);
1492 
1498 extern uint64_t OFRandom64(void);
1499 #ifdef __cplusplus
1500 }
1501 #endif
1502 
1503 OF_ASSUME_NONNULL_END
1504 
1505 #import "OFBlock.h"
1506 #import "OFObject+KeyValueCoding.h"
float y
Definition: OFObject.h:161
bool allowsWeakReference()
Returns whether the object allows a weak reference.
void load()
A method which is called once when the class is loaded into the runtime.
Definition: OFObject.m:395
void * objc_destructInstance(id object)
Destructs the specified object.
Definition: instance.m:75
id objc_constructInstance(Class class_, void *bytes)
Constructs an instance of the specified class in the specified array of bytes.
Definition: instance.m:59
float height
Definition: OFObject.h:207
Definition: OFObject.h:97
A protocol for comparing objects.
Definition: OFObject.h:1384
Definition: OFObject.h:60
void release()
Decreases the retain count.
id copy()
Copies the object.
The root class for all other classes inside ObjFW.
Definition: OFObject.h:686
A class for parsing type encodings and accessing them.
Definition: OFMethodSignature.h:28
float y
Definition: OFObject.h:356
Definition: OFObject.h:58
OFString * description()
Returns a description for the class, which is usually the class name.
bool retainWeakReference()
Retain a weak reference to this object.
instancetype retain()
Increases the retain count.
size_t length
Definition: OFObject.h:110
float x
Definition: OFObject.h:302
float w
Definition: OFObject.h:360
uint16_t OFRandom16(void)
Returns 16 bit or non-cryptographical randomness.
Definition: OFObject.m:178
id mutableCopy()
Creates a mutable copy of the object.
void OFFreeMemory(void *pointer)
Frees memory allocated by OFAllocMemory, OFAllocZeroedMemory or OFResizeMemory.
Definition: OFObject.m:156
void objc_autoreleasePoolPop(void *_Null_unspecified pool)
Drains the specified autorelease pool and all pools on top of it and removes it from the stack of aut...
Definition: OFObject.h:56
A class for handling strings.
Definition: OFString.h:134
A rectangle.
Definition: OFObject.h:249
id copy()
Returns the class.
Definition: OFObject.m:1291
OFComparisonResult
A result of a comparison.
Definition: OFObject.h:54
float y
Definition: OFObject.h:304
void * OFResizeMemory(void *pointer, size_t count, size_t size)
Resizes memory to the specified number of items of the specified size.
Definition: OFObject.m:138
void * OFAllocMemory(size_t count, size_t size)
Allocates memory for the specified number of items of the specified size.
Definition: OFObject.m:101
A class which provides portable threads.
Definition: OFThread.h:61
instancetype autorelease()
Adds the object to the topmost autorelease pool of the thread&#39;s autorelease pool stack.
instancetype self()
Returns the receiver.
uint64_t OFRandom64(void)
Returns 64 bit or non-cryptographical randomness.
Definition: OFObject.m:216
unsigned int retainCount()
Returns the retain count.
void dealloc()
Deallocates the object.
Definition: OFObject.m:1229
OFSize size
Definition: OFObject.h:253
Definition: OFObject.h:92
OFByteOrder
An enum for representing endianness.
Definition: OFObject.h:88
double OFTimeInterval
A time interval in seconds.
Definition: OFObject.h:150
instancetype init()
Initializes an already allocated object.
Definition: OFObject.m:586
bool isProxy()
Returns whether the object is a proxy object.
void initialize()
A method which is called the moment before the first call to the class is being made.
Definition: OFObject.m:434
OFString * className()
Returns the name of the class as a string.
instancetype alloc()
Allocates memory for an instance of the class and sets up the memory pool for the object...
Definition: OFObject.m:438
OFComparisonResult(^ OFComparator)(id left, id right)
A comparator to compare two objects.
Definition: OFObject.h:82
uint32_t OFRandom32(void)
Returns 32 bit or non-cryptographical randomness.
Definition: OFObject.m:200
A size.
Definition: OFObject.h:203
void * OFAllocZeroedMemory(size_t count, size_t size)
Allocates memory for the specified number of items of the specified size and initializes it with zero...
Definition: OFObject.m:119
A protocol for the creation of mutable copies.
Definition: OFObject.h:1367
void *_Null_unspecified objc_autoreleasePoolPush(void)
Creates a new autorelease pool and puts it on top of the stack of autorelease pools.
Definition: autorelease.m:66
A protocol for the creation of copies.
Definition: OFObject.h:1346
float z
Definition: OFObject.h:358
unsigned long hash()
Returns a hash for the object.
size_t location
Definition: OFObject.h:108
Class class()
Returns the class.
OFPoint origin
Definition: OFObject.h:251
float z
Definition: OFObject.h:306
const struct objc_protocol * Protocol
A protocol.
Definition: ObjFWRT.h:113
id(* IMP)(id object, SEL selector,...)
A method implementation.
Definition: ObjFWRT.h:142
float x
Definition: OFObject.h:159
A vector in 3D space.
Definition: OFObject.h:300
Definition: OFObject.h:90
void unload()
A method which is called when the class is unloaded from the runtime.
Definition: OFObject.m:430
A range.
Definition: OFObject.h:106
float width
Definition: OFObject.h:205
A vector in 4D space.
Definition: OFObject.h:352
void OFHashInit(unsigned long *hash)
Initializes the specified hash.
Definition: OFObject.m:236
float x
Definition: OFObject.h:354
OFComparisonResult(* OFCompareFunction)(id left, id right, void *context)
A function to compare two objects.
Definition: OFObject.h:71
A point in 2D space.
Definition: OFObject.h:157
nullable Class superclass()
Returns the superclass of the class.