ObjFW
OFObject.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008-2021 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_OF_OBJECT_H
17 #define OBJFW_OF_OBJECT_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 <stddef.h>
29 #include <stdint.h>
30 #include <stdbool.h>
31 #include <limits.h>
32 
33 #include "block.h"
34 #include "macros.h"
35 #include "once.h"
36 
37 /*
38  * Some versions of MinGW require <winsock2.h> to be included before
39  * <windows.h>. Do this here to make sure this is always done in the correct
40  * order, even if another header includes just <windows.h>.
41  */
42 #ifdef __MINGW32__
43 # include <_mingw.h>
44 # ifdef __MINGW64_VERSION_MAJOR
45 # include <winsock2.h>
46 # include <windows.h>
47 # endif
48 #endif
49 
50 OF_ASSUME_NONNULL_BEGIN
51 
57 typedef enum {
65 
66 #ifdef OF_HAVE_BLOCKS
74 typedef of_comparison_result_t (^of_comparator_t)(id _Nonnull left,
75  id _Nonnull right);
76 #endif
77 
81 typedef enum {
87 
93 struct OF_BOXABLE of_range_t {
95  size_t location;
97  size_t length;
98 };
99 typedef struct of_range_t of_range_t;
100 
108 static OF_INLINE of_range_t OF_CONST_FUNC
109 of_range(size_t start, size_t length)
110 {
111  of_range_t range = { start, length };
112 
113  return range;
114 }
115 
123 static OF_INLINE bool
124 of_range_equal(of_range_t range1, of_range_t range2)
125 {
126  if (range1.location != range2.location)
127  return false;
128 
129  if (range1.length != range2.length)
130  return false;
131 
132  return true;
133 }
134 
138 typedef double of_time_interval_t;
139 
145 struct OF_BOXABLE of_point_t {
147  float x;
149  float y;
150 };
151 typedef struct of_point_t of_point_t;
152 
160 static OF_INLINE of_point_t OF_CONST_FUNC
161 of_point(float x, float y)
162 {
163  of_point_t point = { x, y };
164 
165  return point;
166 }
167 
175 static OF_INLINE bool
176 of_point_equal(of_point_t point1, of_point_t point2)
177 {
178  if (point1.x != point2.x)
179  return false;
180 
181  if (point1.y != point2.y)
182  return false;
183 
184  return true;
185 }
186 
192 struct OF_BOXABLE of_dimension_t {
194  float width;
196  float height;
197 };
198 typedef struct of_dimension_t of_dimension_t;
199 
207 static OF_INLINE of_dimension_t OF_CONST_FUNC
208 of_dimension(float width, float height)
209 {
210  of_dimension_t dimension = { width, height };
211 
212  return dimension;
213 }
214 
222 static OF_INLINE bool
223 of_dimension_equal(of_dimension_t dimension1, of_dimension_t dimension2)
224 {
225  if (dimension1.width != dimension2.width)
226  return false;
227 
228  if (dimension1.height != dimension2.height)
229  return false;
230 
231  return true;
232 }
233 
239 struct OF_BOXABLE of_rectangle_t {
244 };
245 typedef struct of_rectangle_t of_rectangle_t;
246 
256 static OF_INLINE of_rectangle_t OF_CONST_FUNC
257 of_rectangle(float x, float y, float width, float height)
258 {
259  of_rectangle_t rectangle = {
260  of_point(x, y),
261  of_dimension(width, height)
262  };
263 
264  return rectangle;
265 }
266 
274 static OF_INLINE bool
275 of_rectangle_equal(of_rectangle_t rectangle1, of_rectangle_t rectangle2)
276 {
277  if (!of_point_equal(rectangle1.origin, rectangle2.origin))
278  return false;
279 
280  if (!of_dimension_equal(rectangle1.size, rectangle2.size))
281  return false;
282 
283  return true;
284 }
285 
286 #ifdef __OBJC__
287 @class OFMethodSignature;
288 @class OFString;
289 @class OFThread;
290 
296 @protocol OFObject
302 - (Class)class;
303 
309 - (nullable Class)superclass;
310 
323 - (unsigned long)hash;
324 
330 - (unsigned int)retainCount;
331 
337 - (bool)isProxy;
338 
344 - (bool)allowsWeakReference;
345 
352 - (bool)isKindOfClass: (Class)class_;
353 
361 - (bool)isMemberOfClass: (Class)class_;
362 
370 - (bool)respondsToSelector: (SEL)selector;
371 
378 - (bool)conformsToProtocol: (Protocol *)protocol;
379 
386 - (nullable IMP)methodForSelector: (SEL)selector;
387 
394 - (nullable id)performSelector: (SEL)selector;
395 
404 - (nullable id)performSelector: (SEL)selector withObject: (nullable id)object;
405 
416 - (nullable id)performSelector: (SEL)selector
417  withObject: (nullable id)object1
418  withObject: (nullable id)object2;
419 
432 - (nullable id)performSelector: (SEL)selector
433  withObject: (nullable id)object1
434  withObject: (nullable id)object2
435  withObject: (nullable id)object3;
436 
451 - (nullable id)performSelector: (SEL)selector
452  withObject: (nullable id)object1
453  withObject: (nullable id)object2
454  withObject: (nullable id)object3
455  withObject: (nullable id)object4;
456 
469 - (bool)isEqual: (nullable id)object;
470 
477 - (instancetype)retain;
478 
485 - (void)release;
486 
493 - (instancetype)autorelease;
494 
500 - (instancetype)self;
501 
507 - (bool)retainWeakReference;
508 @end
509 #endif
510 
516 #ifdef __OBJC__
517 OF_ROOT_CLASS
518 @interface OFObject <OFObject>
519 {
520 @private
521 # ifndef __clang_analyzer__
522  Class _isa;
523 # else
524  Class _isa __attribute__((__unused__));
525 # endif
526 }
527 
528 # ifdef OF_HAVE_CLASS_PROPERTIES
529 # ifndef __cplusplus
530 @property (class, readonly, nonatomic) Class class;
531 # else
532 @property (class, readonly, nonatomic, getter=class) Class class_;
533 # endif
534 @property (class, readonly, nonatomic) OFString *className;
535 @property (class, readonly, nullable, nonatomic) Class superclass;
536 @property (class, readonly, nonatomic) OFString *description;
537 # endif
538 
539 # ifndef __cplusplus
540 @property (readonly, nonatomic) Class class;
541 # else
542 @property (readonly, nonatomic, getter=class) Class class_;
543 #endif
544 @property OF_NULLABLE_PROPERTY (readonly, nonatomic) Class superclass;
545 @property (readonly, nonatomic) unsigned long hash;
546 @property (readonly, nonatomic) unsigned int retainCount;
547 @property (readonly, nonatomic) bool isProxy;
548 @property (readonly, nonatomic) bool allowsWeakReference;
549 
553 @property (readonly, nonatomic) OFString *className;
554 
561 @property (readonly, nonatomic) OFString *description;
562 
570 + (void)load;
571 
584 + (void)unload;
585 
595 + (void)initialize;
596 
606 + (instancetype)alloc;
607 
613 + (instancetype)new;
614 
620 + (Class)class;
621 
627 + (OFString *)className;
628 
636 + (bool)isSubclassOfClass: (Class)class_;
637 
643 + (nullable Class)superclass;
644 
652 + (bool)instancesRespondToSelector: (SEL)selector;
653 
660 + (bool)conformsToProtocol: (Protocol *)protocol;
661 
670 + (nullable IMP)instanceMethodForSelector: (SEL)selector;
671 
681 + (nullable OFMethodSignature *)
682  instanceMethodSignatureForSelector: (SEL)selector;
683 
691 + (OFString *)description;
692 
700 + (nullable IMP)replaceClassMethod: (SEL)selector
701  withMethodFromClass: (Class)class_;
702 
711 + (nullable IMP)replaceInstanceMethod: (SEL)selector
712  withMethodFromClass: (Class)class_;
713 
732 + (void)inheritMethodsFromClass: (Class)class_;
733 
742 + (bool)resolveClassMethod: (SEL)selector;
743 
752 + (bool)resolveInstanceMethod: (SEL)selector;
753 
762 + (id)copy;
763 
795 - (instancetype)init;
796 
804 - (nullable OFMethodSignature *)methodSignatureForSelector: (SEL)selector;
805 
813 - (void)dealloc;
814 
821 - (void)performSelector: (SEL)selector afterDelay: (of_time_interval_t)delay;
822 
832 - (void)performSelector: (SEL)selector
833  withObject: (nullable id)object
834  afterDelay: (of_time_interval_t)delay;
835 
847 - (void)performSelector: (SEL)selector
848  withObject: (nullable id)object1
849  withObject: (nullable id)object2
850  afterDelay: (of_time_interval_t)delay;
851 
865 - (void)performSelector: (SEL)selector
866  withObject: (nullable id)object1
867  withObject: (nullable id)object2
868  withObject: (nullable id)object3
869  afterDelay: (of_time_interval_t)delay;
870 
886 - (void)performSelector: (SEL)selector
887  withObject: (nullable id)object1
888  withObject: (nullable id)object2
889  withObject: (nullable id)object3
890  withObject: (nullable id)object4
891  afterDelay: (of_time_interval_t)delay;
892 
893 # ifdef OF_HAVE_THREADS
901 - (void)performSelector: (SEL)selector
902  onThread: (OFThread *)thread
903  waitUntilDone: (bool)waitUntilDone;
904 
915 - (void)performSelector: (SEL)selector
916  onThread: (OFThread *)thread
917  withObject: (nullable id)object
918  waitUntilDone: (bool)waitUntilDone;
919 
932 - (void)performSelector: (SEL)selector
933  onThread: (OFThread *)thread
934  withObject: (nullable id)object1
935  withObject: (nullable id)object2
936  waitUntilDone: (bool)waitUntilDone;
937 
952 - (void)performSelector: (SEL)selector
953  onThread: (OFThread *)thread
954  withObject: (nullable id)object1
955  withObject: (nullable id)object2
956  withObject: (nullable id)object3
957  waitUntilDone: (bool)waitUntilDone;
958 
975 - (void)performSelector: (SEL)selector
976  onThread: (OFThread *)thread
977  withObject: (nullable id)object1
978  withObject: (nullable id)object2
979  withObject: (nullable id)object3
980  withObject: (nullable id)object4
981  waitUntilDone: (bool)waitUntilDone;
982 
989 - (void)performSelectorOnMainThread: (SEL)selector
990  waitUntilDone: (bool)waitUntilDone;
991 
1001 - (void)performSelectorOnMainThread: (SEL)selector
1002  withObject: (nullable id)object
1003  waitUntilDone: (bool)waitUntilDone;
1004 
1016 - (void)performSelectorOnMainThread: (SEL)selector
1017  withObject: (nullable id)object1
1018  withObject: (nullable id)object2
1019  waitUntilDone: (bool)waitUntilDone;
1020 
1034 - (void)performSelectorOnMainThread: (SEL)selector
1035  withObject: (nullable id)object1
1036  withObject: (nullable id)object2
1037  withObject: (nullable id)object3
1038  waitUntilDone: (bool)waitUntilDone;
1039 
1055 - (void)performSelectorOnMainThread: (SEL)selector
1056  withObject: (nullable id)object1
1057  withObject: (nullable id)object2
1058  withObject: (nullable id)object3
1059  withObject: (nullable id)object4
1060  waitUntilDone: (bool)waitUntilDone;
1061 
1070 - (void)performSelector: (SEL)selector
1071  onThread: (OFThread *)thread
1072  afterDelay: (of_time_interval_t)delay;
1073 
1084 - (void)performSelector: (SEL)selector
1085  onThread: (OFThread *)thread
1086  withObject: (nullable id)object
1087  afterDelay: (of_time_interval_t)delay;
1088 
1101 - (void)performSelector: (SEL)selector
1102  onThread: (OFThread *)thread
1103  withObject: (nullable id)object1
1104  withObject: (nullable id)object2
1105  afterDelay: (of_time_interval_t)delay;
1106 
1121 - (void)performSelector: (SEL)selector
1122  onThread: (OFThread *)thread
1123  withObject: (nullable id)object1
1124  withObject: (nullable id)object2
1125  withObject: (nullable id)object3
1126  afterDelay: (of_time_interval_t)delay;
1127 
1144 - (void)performSelector: (SEL)selector
1145  onThread: (OFThread *)thread
1146  withObject: (nullable id)object1
1147  withObject: (nullable id)object2
1148  withObject: (nullable id)object3
1149  withObject: (nullable id)object4
1150  afterDelay: (of_time_interval_t)delay;
1151 # endif
1152 
1164 - (nullable id)forwardingTargetForSelector: (SEL)selector;
1165 
1174 - (void)doesNotRecognizeSelector: (SEL)selector OF_NO_RETURN;
1175 @end
1176 #else
1177 typedef void OFObject;
1178 #endif
1179 
1180 #ifdef __OBJC__
1186 @protocol OFCopying
1196 - (id)copy;
1197 @end
1198 
1207 @protocol OFMutableCopying
1213 - (id)mutableCopy;
1214 @end
1215 
1223 @protocol OFComparing
1230 - (of_comparison_result_t)compare: (id <OFComparing>)object;
1231 @end
1232 #endif
1233 
1234 #ifdef __cplusplus
1235 extern "C" {
1236 #endif
1251 extern void *_Nullable of_alloc(size_t count, size_t size)
1252  OF_WARN_UNUSED_RESULT;
1253 
1268 extern void *_Nullable of_alloc_zeroed(size_t count, size_t size)
1269  OF_WARN_UNUSED_RESULT;
1270 
1287 extern void *_Nullable of_realloc(void *_Nullable pointer, size_t count,
1288  size_t size) OF_WARN_UNUSED_RESULT;
1289 
1290 #ifdef OF_APPLE_RUNTIME
1291 extern void *_Null_unspecified objc_autoreleasePoolPush(void);
1292 extern void objc_autoreleasePoolPop(void *_Null_unspecified pool);
1293 # ifndef __OBJC2__
1294 extern id _Nullable objc_constructInstance(Class _Nullable class_,
1295  void *_Nullable bytes);
1296 extern void *_Nullable objc_destructInstance(id _Nullable object);
1297 # endif
1298 #endif
1299 extern id of_alloc_object(Class class_, size_t extraSize,
1300  size_t extraAlignment, void *_Nullable *_Nullable extra);
1301 extern void OF_NO_RETURN_FUNC of_method_not_found(id self, SEL _cmd);
1302 extern uint32_t of_hash_seed;
1303 /* These do *NOT* provide cryptographically secure randomness! */
1304 extern uint16_t of_random16(void);
1305 extern uint32_t of_random32(void);
1306 extern uint64_t of_random64(void);
1307 #ifdef __cplusplus
1308 }
1309 #endif
1310 
1311 OF_ASSUME_NONNULL_END
1312 
1313 #ifdef __OBJC__
1314 # import "OFObject+KeyValueCoding.h"
1315 # import "OFObject+Serialization.h"
1316 #endif
1317 
1318 #endif
of_byte_order_t
An enum for storing endianess.
Definition: OFObject.h:81
@ OF_BYTE_ORDER_BIG_ENDIAN
Definition: OFObject.h:83
@ OF_BYTE_ORDER_LITTLE_ENDIAN
Definition: OFObject.h:85
of_comparison_result_t(^ of_comparator_t)(id _Nonnull left, id _Nonnull right)
A comparator to compare two objects.
Definition: OFObject.h:74
void *_Nullable of_realloc(void *_Nullable pointer, size_t count, size_t size) 1
Resizes memory to the specified number of items of the specified size.
of_comparison_result_t
A result of a comparison.
Definition: OFObject.h:57
@ OF_ORDERED_DESCENDING
Definition: OFObject.h:63
@ OF_ORDERED_ASCENDING
Definition: OFObject.h:59
@ OF_ORDERED_SAME
Definition: OFObject.h:61
double of_time_interval_t
A time interval in seconds.
Definition: OFObject.h:138
void *_Nullable of_alloc(size_t count, size_t size) 1
Allocates memory for the specified number of items of the specified size.
Definition: OFObject.m:100
void *_Nullable of_alloc_zeroed(size_t count, size_t size) 1
Allocates memory for the specified number of items of the specified size and initializes it with zero...
Definition: OFObject.m:118
struct objc_object * id
A pointer to any object.
Definition: ObjFWRT.h:90
id _Nullable(* IMP)(id _Nonnull object, SEL _Nonnull selector,...)
A method implemenation.
Definition: ObjFWRT.h:142
id _Nullable objc_constructInstance(Class _Nullable class_, void *_Nullable bytes)
Constructs an instance of the specified class in the specified array of bytes.
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:61
struct objc_class * Class
A pointer to a class.
Definition: ObjFWRT.h:85
void *_Nullable objc_destructInstance(id _Nullable object)
Destructs the specified object.
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:28
The root class for all other classes inside ObjFW.
Definition: OFObject.h:520
OFString * description
A description for the object.
Definition: OFObject.h:562
OFString * className
The name of the object's class.
Definition: OFObject.h:554
instancetype init()
Initializes an already allocated object.
Definition: OFObject.m:547
void dealloc()
Deallocates the object.
Definition: OFObject.m:1190
id copy()
Returns the class.
Definition: OFObject.m:1248
void unload()
A method which is called when the class is unloaded from the runtime.
Definition: OFObject.m:384
instancetype alloc()
Allocates memory for an instance of the class and sets up the memory pool for the object.
Definition: OFObject.m:392
instancetype new()
Calls alloc on self and then init on the returned object.
Definition: OFObject.m:397
void initialize()
A method which is called the moment before the first call to the class is being made.
Definition: OFObject.m:388
void load()
A method which is called once when the class is loaded into the runtime.
Definition: OFObject.m:349
A class for handling strings.
Definition: OFString.h:132
A class which provides portable threads.
Definition: OFThread.h:63
A protocol for comparing objects.
Definition: OFObject.h:1224
A protocol for the creation of copies.
Definition: OFObject.h:1187
id copy()
Copies the object.
A protocol for the creation of mutable copies.
Definition: OFObject.h:1208
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 dimension.
Definition: OFObject.h:192
float width
Definition: OFObject.h:194
float height
Definition: OFObject.h:196
A point.
Definition: OFObject.h:145
float y
Definition: OFObject.h:149
float x
Definition: OFObject.h:147
A range.
Definition: OFObject.h:93
size_t length
Definition: OFObject.h:97
size_t location
Definition: OFObject.h:95
A rectangle.
Definition: OFObject.h:239
of_dimension_t size
Definition: OFObject.h:243
of_point_t origin
Definition: OFObject.h:241