9781fad1d7fc8d95eda85087753f2ea59d4fe11b
[gcc.git] / libobjc / Object.m
1 /* The implementation of class Object for Objective-C.
2 Copyright (C) 1993, 1994, 1995, 1997, 2002, 2009, 2010
3 Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3, or (at your option) any
10 later version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
16
17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
20
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 <http://www.gnu.org/licenses/>. */
25
26 #include "objc-private/common.h"
27 #include <stdarg.h>
28 #include <string.h> /* For strcmp. */
29 #include <errno.h>
30 #include "objc/Object.h"
31 #include "objc/Protocol.h"
32 #include "objc/objc-api.h"
33
34 @implementation Object
35
36 - (Class)class
37 {
38 return object_get_class (self);
39 }
40
41 - (BOOL)isEqual: (id)anObject
42 {
43 return self == anObject;
44 }
45
46 @end
47
48 /* The following methods were deprecated in GCC 4.6.0 and will be
49 removed in the next GCC release. */
50 @implementation Object (Deprecated)
51
52 + initialize
53 {
54 return self;
55 }
56
57 - init
58 {
59 return self;
60 }
61
62 + new
63 {
64 return [[self alloc] init];
65 }
66
67 + alloc
68 {
69 return class_create_instance(self);
70 }
71
72 - free
73 {
74 return object_dispose(self);
75 }
76
77 - copy
78 {
79 return [[self shallowCopy] deepen];
80 }
81
82 - shallowCopy
83 {
84 return object_copy(self);
85 }
86
87 - deepen
88 {
89 return self;
90 }
91
92 - deepCopy
93 {
94 return [self copy];
95 }
96
97 - (Class)superClass
98 {
99 return object_get_super_class(self);
100 }
101
102 - (MetaClass)metaClass
103 {
104 return object_get_meta_class(self);
105 }
106
107 - (const char *)name
108 {
109 return object_get_class_name(self);
110 }
111
112 - self
113 {
114 return self;
115 }
116
117 - (unsigned int)hash
118 {
119 return (size_t)self;
120 }
121
122 - (int)compare:(id)anotherObject;
123 {
124 if ([self isEqual:anotherObject])
125 return 0;
126 // Ordering objects by their address is pretty useless,
127 // so subclasses should override this is some useful way.
128 else if ((id)self > anotherObject)
129 return 1;
130 else
131 return -1;
132 }
133
134 - (BOOL)isMetaClass
135 {
136 return NO;
137 }
138
139 - (BOOL)isClass
140 {
141 return object_is_class(self);
142 }
143
144 - (BOOL)isInstance
145 {
146 return object_is_instance(self);
147 }
148
149 - (BOOL)isKindOf:(Class)aClassObject
150 {
151 Class class;
152
153 for (class = self->isa; class!=Nil; class = class_get_super_class(class))
154 if (class==aClassObject)
155 return YES;
156 return NO;
157 }
158
159 - (BOOL)isMemberOf:(Class)aClassObject
160 {
161 return self->isa==aClassObject;
162 }
163
164 - (BOOL)isKindOfClassNamed:(const char *)aClassName
165 {
166 Class class;
167
168 if (aClassName!=NULL)
169 for (class = self->isa; class!=Nil; class = class_get_super_class(class))
170 if (!strcmp(class_get_class_name(class), aClassName))
171 return YES;
172 return NO;
173 }
174
175 - (BOOL)isMemberOfClassNamed:(const char *)aClassName
176 {
177 return ((aClassName!=NULL)
178 &&!strcmp(class_get_class_name(self->isa), aClassName));
179 }
180
181 + (BOOL)instancesRespondTo:(SEL)aSel
182 {
183 return class_get_instance_method(self, aSel) != (Method_t)0;
184 }
185
186 - (BOOL)respondsTo:(SEL)aSel
187 {
188 return ((object_is_instance(self)
189 ?class_get_instance_method(self->isa, aSel)
190 :class_get_class_method(self->isa, aSel)) != (Method_t)0);
191 }
192
193 + (IMP)instanceMethodFor:(SEL)aSel
194 {
195 return method_get_imp(class_get_instance_method(self, aSel));
196 }
197
198 // Indicates if the receiving class or instance conforms to the given protocol
199 // not usually overridden by subclasses
200 //
201 // Modified 9/5/94 to always search the class object's protocol list, rather
202 // than the meta class.
203
204 + (BOOL) conformsTo: (Protocol*)aProtocol
205 {
206 size_t i;
207 struct objc_protocol_list* proto_list;
208 id parent;
209
210 for (proto_list = ((Class)self)->protocols;
211 proto_list; proto_list = proto_list->next)
212 {
213 for (i=0; i < proto_list->count; i++)
214 {
215 if ([proto_list->list[i] conformsTo: aProtocol])
216 return YES;
217 }
218 }
219
220 if ((parent = [self superClass]))
221 return [parent conformsTo: aProtocol];
222 else
223 return NO;
224 }
225
226 - (BOOL) conformsTo: (Protocol*)aProtocol
227 {
228 return [[self class] conformsTo:aProtocol];
229 }
230
231 - (IMP)methodFor:(SEL)aSel
232 {
233 return (method_get_imp(object_is_instance(self)
234 ?class_get_instance_method(self->isa, aSel)
235 :class_get_class_method(self->isa, aSel)));
236 }
237
238 + (struct objc_method_description *)descriptionForInstanceMethod:(SEL)aSel
239 {
240 return ((struct objc_method_description *)
241 class_get_instance_method(self, aSel));
242 }
243
244 - (struct objc_method_description *)descriptionForMethod:(SEL)aSel
245 {
246 return ((struct objc_method_description *)
247 (object_is_instance(self)
248 ?class_get_instance_method(self->isa, aSel)
249 :class_get_class_method(self->isa, aSel)));
250 }
251
252 - (retval_t)performv:(SEL)aSel :(arglist_t)argFrame
253 {
254 return objc_msg_sendv(self, aSel, argFrame);
255 }
256
257 + poseAs:(Class)aClassObject
258 {
259 return class_pose_as(self, aClassObject);
260 }
261
262 - (Class)transmuteClassTo:(Class)aClassObject
263 {
264 if (object_is_instance(self))
265 if (class_is_class(aClassObject))
266 if (class_get_instance_size(aClassObject)==class_get_instance_size(isa))
267 if ([self isKindOf:aClassObject])
268 {
269 Class old_isa = isa;
270 isa = aClassObject;
271 return old_isa;
272 }
273 return nil;
274 }
275
276 + (int)version
277 {
278 return class_get_version(self);
279 }
280
281 + setVersion:(int)aVersion
282 {
283 class_set_version(self, aVersion);
284 return self;
285 }
286
287 @end