ObjFW
OFObject.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008-2023 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
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
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;
722 
729 @property (readonly, nonatomic) OFString *description;
730 
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
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 
1382 @protocol OFComparing
1389 - (OFComparisonResult)compare: (id <OFComparing>)object;
1390 @end
1391 
1392 #ifdef __cplusplus
1393 extern "C" {
1394 #endif
1409 extern void *_Nullable OFAllocMemory(size_t count, size_t size)
1410  OF_WARN_UNUSED_RESULT;
1411 
1426 extern void *_Nullable OFAllocZeroedMemory(size_t count, size_t size)
1427  OF_WARN_UNUSED_RESULT;
1428 
1446 extern void *_Nullable OFResizeMemory(void *_Nullable pointer, size_t count,
1447  size_t size) OF_WARN_UNUSED_RESULT;
1448 
1456 extern void OFFreeMemory(void *_Nullable pointer);
1457 
1458 #ifdef OF_APPLE_RUNTIME
1459 extern void *_Null_unspecified objc_autoreleasePoolPush(void);
1460 extern void objc_autoreleasePoolPop(void *_Null_unspecified pool);
1461 # ifndef __OBJC2__
1462 extern id _Nullable objc_constructInstance(Class _Nullable class_,
1463  void *_Nullable bytes);
1464 extern void *_Nullable objc_destructInstance(id _Nullable object);
1465 # endif
1466 #endif
1467 extern id OFAllocObject(Class class_, size_t extraSize, size_t extraAlignment,
1468  void *_Nullable *_Nullable extra);
1469 extern void OF_NO_RETURN_FUNC OFMethodNotFound(id self, SEL _cmd);
1470 
1476 extern void OFHashInit(unsigned long *_Nonnull hash);
1477 
1483 extern uint16_t OFRandom16(void);
1484 
1490 extern uint32_t OFRandom32(void);
1491 
1497 extern uint64_t OFRandom64(void);
1498 #ifdef __cplusplus
1499 }
1500 #endif
1501 
1502 OF_ASSUME_NONNULL_END
1503 
1504 #import "OFBlock.h"
1505 #import "OFObject+KeyValueCoding.h"
OFComparisonResult
A result of a comparison.
Definition: OFObject.h:54
@ OFOrderedAscending
Definition: OFObject.h:56
@ OFOrderedDescending
Definition: OFObject.h:60
@ OFOrderedSame
Definition: OFObject.h:58
void OFHashInit(unsigned long *hash)
Initializes the specified hash.
Definition: OFObject.m:236
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
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 OFFreeMemory(void *pointer)
Frees memory allocated by OFAllocMemory, OFAllocZeroedMemory or OFResizeMemory.
Definition: OFObject.m:156
double OFTimeInterval
A time interval in seconds.
Definition: OFObject.h:150
void * OFAllocMemory(size_t count, size_t size)
Allocates memory for the specified number of items of the specified size.
Definition: OFObject.m:101
uint64_t OFRandom64(void)
Returns 64 bit or non-cryptographical randomness.
Definition: OFObject.m:216
OFByteOrder
An enum for representing endianess.
Definition: OFObject.h:88
@ OFByteOrderBigEndian
Definition: OFObject.h:90
@ OFByteOrderLittleEndian
Definition: OFObject.h:92
@ OFByteOrderNative
Definition: OFObject.h:97
uint16_t OFRandom16(void)
Returns 16 bit or non-cryptographical randomness.
Definition: OFObject.m:178
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
OFComparisonResult(* OFCompareFunction)(id left, id right, void *context)
A function to compare two objects.
Definition: OFObject.h:71
id(* IMP)(id object, SEL selector,...)
A method implemenation.
Definition: ObjFWRT.h:142
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
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
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...
const struct objc_protocol * Protocol
A protocol.
Definition: ObjFWRT.h:113
A class for parsing type encodings and accessing them.
Definition: OFMethodSignature.h:29
The root class for all other classes inside ObjFW.
Definition: OFObject.h:688
OFString * description
A description for the object.
Definition: OFObject.h:730
OFString * className
The name of the object's class.
Definition: OFObject.h:722
instancetype init()
Initializes an already allocated object.
Definition: OFObject.m:586
void dealloc()
Deallocates the object.
Definition: OFObject.m:1229
id copy()
Returns the class.
Definition: OFObject.m:1291
void unload()
A method which is called when the class is unloaded from the runtime.
Definition: OFObject.m:430
instancetype alloc()
Allocates memory for an instance of the class and sets up the memory pool for the object.
Definition: OFObject.m:438
void initialize()
A method which is called the moment before the first call to the class is being made.
Definition: OFObject.m:434
void load()
A method which is called once when the class is loaded into the runtime.
Definition: OFObject.m:395
A class for handling strings.
Definition: OFString.h:135
A class which provides portable threads.
Definition: OFThread.h:62
A protocol for comparing objects.
Definition: OFObject.h:1383
A protocol for the creation of copies.
Definition: OFObject.h:1346
id copy()
Copies the object.
A protocol for the creation of mutable copies.
Definition: OFObject.h:1367
id mutableCopy()
Creates a mutable copy of the object.
instancetype autorelease()
Adds the object to the topmost autorelease pool of the thread's autorelease pool stack.
instancetype self()
Returns the receiver.
void release()
Decreases the retain count.
instancetype retain()
Increases the retain count.
bool retainWeakReference()
Retain a weak reference to this object.
A point in 2D space.
Definition: OFObject.h:157
float y
Definition: OFObject.h:161
float x
Definition: OFObject.h:159
A range.
Definition: OFObject.h:106
size_t length
Definition: OFObject.h:110
size_t location
Definition: OFObject.h:108
A rectangle.
Definition: OFObject.h:249
OFPoint origin
Definition: OFObject.h:251
OFSize size
Definition: OFObject.h:253
A size.
Definition: OFObject.h:203
float width
Definition: OFObject.h:205
float height
Definition: OFObject.h:207
A vector in 3D space.
Definition: OFObject.h:300
float x
Definition: OFObject.h:302
float y
Definition: OFObject.h:304
float z
Definition: OFObject.h:306
A vector in 4D space.
Definition: OFObject.h:352
float x
Definition: OFObject.h:354
float z
Definition: OFObject.h:358
float y
Definition: OFObject.h:356
float w
Definition: OFObject.h:360