OSDN Git Service

In libobjc/:
[pf3gnuchains/gcc-fork.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 <errno.h>
29 #include "objc/Object.h"
30 #include "objc/Protocol.h"
31 #include "objc/objc-api.h"
32
33 @implementation Object
34
35 - (Class)class
36 {
37   return object_get_class (self);
38 }
39
40 - (BOOL)isEqual: (id)anObject
41 {
42   return self == anObject;
43 }
44
45 @end
46
47 /* The following methods were deprecated in GCC 4.6.0 and will be
48    removed in the next GCC release.  */
49 @implementation Object (Deprecated)
50
51 + initialize
52 {
53   return self;
54 }
55
56 - init
57 {
58   return self;
59 }
60
61 + new
62 {
63   return [[self alloc] init];
64 }
65
66 + alloc
67 {
68   return class_create_instance(self);
69 }
70
71 - free
72 {
73   return object_dispose(self);
74 }
75
76 - copy
77 {
78   return [[self shallowCopy] deepen];
79 }
80
81 - shallowCopy
82 {
83   return object_copy(self);
84 }
85
86 - deepen
87 {
88   return self;
89 }
90
91 - deepCopy
92 {
93   return [self copy];
94 }
95
96 - (Class)superClass
97 {
98   return object_get_super_class(self);
99 }
100
101 - (MetaClass)metaClass
102 {
103   return object_get_meta_class(self);
104 }
105
106 - (const char *)name
107 {
108   return object_get_class_name(self);
109 }
110
111 - self
112 {
113   return self;
114 }
115
116 - (unsigned int)hash
117 {
118   return (size_t)self;
119 }
120
121 - (int)compare:(id)anotherObject;
122 {
123   if ([self isEqual:anotherObject])
124     return 0;
125   // Ordering objects by their address is pretty useless, 
126   // so subclasses should override this is some useful way.
127   else if ((id)self > anotherObject)
128     return 1;
129   else 
130     return -1;
131 }
132
133 - (BOOL)isMetaClass
134 {
135   return NO;
136 }
137
138 - (BOOL)isClass
139 {
140   return object_is_class(self);
141 }
142
143 - (BOOL)isInstance
144 {
145   return object_is_instance(self);
146 }
147
148 - (BOOL)isKindOf:(Class)aClassObject
149 {
150   Class class;
151
152   for (class = self->isa; class!=Nil; class = class_get_super_class(class))
153     if (class==aClassObject)
154       return YES;
155   return NO;
156 }
157
158 - (BOOL)isMemberOf:(Class)aClassObject
159 {
160   return self->isa==aClassObject;
161 }
162
163 - (BOOL)isKindOfClassNamed:(const char *)aClassName
164 {
165   Class class;
166
167   if (aClassName!=NULL)
168     for (class = self->isa; class!=Nil; class = class_get_super_class(class))
169       if (!strcmp(class_get_class_name(class), aClassName))
170         return YES;
171   return NO;
172 }
173
174 - (BOOL)isMemberOfClassNamed:(const char *)aClassName
175 {
176   return ((aClassName!=NULL)
177           &&!strcmp(class_get_class_name(self->isa), aClassName));
178 }
179
180 + (BOOL)instancesRespondTo:(SEL)aSel
181 {
182   return class_get_instance_method(self, aSel) != (Method_t)0;
183 }
184
185 - (BOOL)respondsTo:(SEL)aSel
186 {
187   return ((object_is_instance(self)
188            ?class_get_instance_method(self->isa, aSel)
189            :class_get_class_method(self->isa, aSel)) != (Method_t)0);
190 }
191
192 + (IMP)instanceMethodFor:(SEL)aSel
193 {
194   return method_get_imp(class_get_instance_method(self, aSel));
195 }
196
197 // Indicates if the receiving class or instance conforms to the given protocol
198 // not usually overridden by subclasses
199 //
200 // Modified 9/5/94 to always search the class object's protocol list, rather
201 // than the meta class.
202
203 + (BOOL) conformsTo: (Protocol*)aProtocol
204 {
205   size_t i;
206   struct objc_protocol_list* proto_list;
207   id parent;
208
209   for (proto_list = ((Class)self)->protocols;
210        proto_list; proto_list = proto_list->next)
211     {
212       for (i=0; i < proto_list->count; i++)
213       {
214         if ([proto_list->list[i] conformsTo: aProtocol])
215           return YES;
216       }
217     }
218
219   if ((parent = [self superClass]))
220     return [parent conformsTo: aProtocol];
221   else
222     return NO;
223 }
224
225 - (BOOL) conformsTo: (Protocol*)aProtocol
226 {
227   return [[self class] conformsTo:aProtocol];
228 }
229
230 - (IMP)methodFor:(SEL)aSel
231 {
232   return (method_get_imp(object_is_instance(self)
233                          ?class_get_instance_method(self->isa, aSel)
234                          :class_get_class_method(self->isa, aSel)));
235 }
236
237 + (struct objc_method_description *)descriptionForInstanceMethod:(SEL)aSel
238 {
239   return ((struct objc_method_description *)
240            class_get_instance_method(self, aSel));
241 }
242
243 - (struct objc_method_description *)descriptionForMethod:(SEL)aSel
244 {
245   return ((struct objc_method_description *)
246            (object_is_instance(self)
247             ?class_get_instance_method(self->isa, aSel)
248             :class_get_class_method(self->isa, aSel)));
249 }
250
251 - (retval_t)forward:(SEL)aSel :(arglist_t)argFrame
252 {
253   (void) argFrame; /* UNUSED */
254   return (retval_t)[self doesNotRecognize: aSel];
255 }
256
257 - (retval_t)performv:(SEL)aSel :(arglist_t)argFrame
258 {
259   return objc_msg_sendv(self, aSel, argFrame);
260 }
261
262 + poseAs:(Class)aClassObject
263 {
264   return class_pose_as(self, aClassObject);
265 }
266
267 - (Class)transmuteClassTo:(Class)aClassObject
268 {
269   if (object_is_instance(self))
270     if (class_is_class(aClassObject))
271       if (class_get_instance_size(aClassObject)==class_get_instance_size(isa))
272         if ([self isKindOf:aClassObject])
273           {
274             Class old_isa = isa;
275             isa = aClassObject;
276             return old_isa;
277           }
278   return nil;
279 }
280
281 + (int)version
282 {
283   return class_get_version(self);
284 }
285
286 + setVersion:(int)aVersion
287 {
288   class_set_version(self, aVersion);
289   return self;
290 }
291
292 + (int)streamVersion: (TypedStream*)aStream
293 {
294   if (aStream->mode == OBJC_READONLY)
295     return objc_get_stream_class_version (aStream, self);
296   else
297     return class_get_version (self);
298 }
299
300 // These are used to write or read the instance variables 
301 // declared in this particular part of the object.  Subclasses
302 // should extend these, by calling [super read/write: aStream]
303 // before doing their own archiving.  These methods are private, in
304 // the sense that they should only be called from subclasses.
305
306 - read: (TypedStream*)aStream
307 {
308   (void) aStream; /* UNUSED */
309   // [super read: aStream];  
310   return self;
311 }
312
313 - write: (TypedStream*)aStream
314 {
315   (void) aStream; /* UNUSED */
316   // [super write: aStream];
317   return self;
318 }
319
320 - awake
321 {
322   // [super awake];
323   return self;
324 }
325
326 @end