Objectively
Ultra-lightweight object oriented framework for GNU C.
Loading...
Searching...
No Matches
Class.h File Reference

Classes describe the state and behavior of an Objectively type. More...

Go to the source code of this file.

Data Structures

struct  Class
 The runtime representation of a Class. More...
 
struct  ClassDef
 ClassDefs are passed to _initialize via an archetype to initialize a Class. More...
 

Macros

#define alloc(type)    ((type *) _alloc(_##type()))
 Allocate and initialize and instance of type.
 
#define cast(type, obj)    ((type *) _cast(_##type(), (const ident) obj))
 Safely cast obj to type.
 
#define classnameof(obj)    classof(obj)->def.name
 Resolve the Class name of the given Object instance.
 
#define classof(obj)    ((Object *) obj)->clazz
 Resolve the Class of an Object instance.
 
#define instanceof(type, obj)    (isobject(obj) && $((Object *) obj, isKindOfClass, _##type()))
 Test if the given pointer is an instance of the specified type.
 
#define interfaceof(type, clazz)    ((type##Interface *) (clazz)->interface)
 Resolve the typed interface of a Class.
 
#define isobject(obj)    (obj && *((unsigned int *) obj) == OBJECTIVELY_MAGIC)
 Test if the given pointer is an Object.
 
#define obj
 
#define OBJECTIVELY_MAGIC   0xdeadbeef
 The header value identifying Objectively types.
 
#define super(type, obj, method, ...)    interfaceof(type, _Class()->def.superclass)->method(cast(type, obj), ## __VA_ARGS__)
 
#define type
 

Functions

OBJECTIVELY_EXPORT ident _alloc (Class *clazz)
 Instantiate a type through the given Class.
 
OBJECTIVELY_EXPORT ident _cast (const Class *clazz, const ident obj)
 Perform a type-checking cast.
 
OBJECTIVELY_EXPORT Class_initialize (const ClassDef *clazz)
 Initializes the given Class.
 
OBJECTIVELY_EXPORT ClassclassForName (const char *name)
 
OBJECTIVELY_EXPORT ident release (ident obj)
 Atomically decrement the given Object's reference count. If the resulting reference count is 0, the Object is deallocated.
 
OBJECTIVELY_EXPORT ident retain (ident obj)
 Atomically increment the given Object's reference count.
 

Variables

OBJECTIVELY_EXPORT size_t _pageSize
 The page size, in bytes, of the target host.
 

Detailed Description

Classes describe the state and behavior of an Objectively type.

Definition in file Class.h.

Macro Definition Documentation

◆ alloc

#define alloc (   type)     ((type *) _alloc(_##type()))

Allocate and initialize and instance of type.

Definition at line 176 of file Class.h.

206 { \
207 typeof(obj) _obj = obj; \
208 _obj->interface->method(_obj, ## __VA_ARGS__); \
209 })
210
214#define $$(type, method, ...) \
215 ({ \
216 interfaceof(type, _##type())->method(__VA_ARGS__); \
217 })
218
222#define super(type, obj, method, ...) \
223 interfaceof(type, _Class()->def.superclass)->method(cast(type, obj), ## __VA_ARGS__)
#define _Class
Definition Array.c:75
#define obj
#define cast(type, obj)
Safely cast obj to type.
Definition Class.h:182
#define type
#define super(type, obj, method,...)

◆ cast

#define cast (   type,
  obj 
)     ((type *) _cast(_##type(), (const ident) obj))

Safely cast obj to type.

Definition at line 182 of file Class.h.

◆ classnameof

#define classnameof (   obj)     classof(obj)->def.name

Resolve the Class name of the given Object instance.

Definition at line 194 of file Class.h.

◆ classof

#define classof (   obj)     ((Object *) obj)->clazz

Resolve the Class of an Object instance.

Definition at line 188 of file Class.h.

◆ instanceof

#define instanceof (   type,
  obj 
)     (isobject(obj) && $((Object *) obj, isKindOfClass, _##type()))

Test if the given pointer is an instance of the specified type.

Definition at line 170 of file Class.h.

◆ interfaceof

#define interfaceof (   type,
  clazz 
)     ((type##Interface *) (clazz)->interface)

Resolve the typed interface of a Class.

Definition at line 200 of file Class.h.

◆ isobject

#define isobject (   obj)     (obj && *((unsigned int *) obj) == OBJECTIVELY_MAGIC)

Test if the given pointer is an Object.

Definition at line 164 of file Class.h.

◆ obj

#define obj
Value:
, method, ...) \
({ \
typeof(obj) _obj = obj; \
_obj->interface->method(_obj, ## __VA_ARGS__); \
})

◆ OBJECTIVELY_MAGIC

#define OBJECTIVELY_MAGIC   0xdeadbeef

The header value identifying Objectively types.

Definition at line 159 of file Class.h.

◆ super

#define super (   type,
  obj,
  method,
  ... 
)     interfaceof(type, _Class()->def.superclass)->method(cast(type, obj), ## __VA_ARGS__)

◆ type

#define type
Value:
, method, ...) \
({ \
interfaceof(type, _##type())->method(__VA_ARGS__); \
})

Function Documentation

◆ _alloc()

OBJECTIVELY_EXPORT ident _alloc ( Class clazz)

Instantiate a type through the given Class.

Definition at line 123 of file Class.c.

123 {
124
125 ident obj = calloc(1, clazz->def.instanceSize);
126 assert(obj);
127
128 Object *object = (Object *) obj;
129
130 object->magic = OBJECTIVELY_MAGIC;
131 object->clazz = clazz;
132 object->referenceCount = 1;
133
134 ident interface = clazz->interface;
135 do {
136 *(ident *) (obj + clazz->def.interfaceOffset) = interface;
137 } while ((clazz = clazz->def.superclass));
138
139 return obj;
140}
#define OBJECTIVELY_MAGIC
The header value identifying Objectively types.
Definition Class.h:159
void * ident
The identity type, similar to Objective-C id.
Definition Types.h:49
size_t instanceSize
The instance size (required).
Definition Class.h:69
ptrdiff_t interfaceOffset
The interface offset (required).
Definition Class.h:74
Class * superclass
The superclass (required). e.g. _Object().
Definition Class.h:89
ClassDef def
The Class definition.
Definition Class.h:100
Object is the root Class of The Objectively Class hierarchy.
Definition Object.h:46
unsigned int magic
A header to allow introspection of Object types.
Definition Object.h:50

◆ _cast()

OBJECTIVELY_EXPORT ident _cast ( const Class clazz,
const ident  obj 
)

Perform a type-checking cast.

Definition at line 142 of file Class.c.

142 {
143
144 if (obj) {
145 const Class *c = ((Object *) obj)->clazz;
146 while (c) {
147
148 // as a special case, we optimize for _Object
149 if (c == clazz || clazz == _Object()) {
150 break;
151 }
152
153 c = c->def.superclass;
154 }
155 assert(c);
156 }
157
158 return (ident) obj;
159}
Class * _Object(void)
Definition Object.c:136
The runtime representation of a Class.
Definition Class.h:95

◆ _initialize()

OBJECTIVELY_EXPORT Class * _initialize ( const ClassDef clazz)

Initializes the given Class.

Parameters
clazzThe Class descriptor.
Returns
The initialized Class.

Definition at line 86 of file Class.c.

86 {
87
88 static Once once;
89 do_once(&once, setup());
90
91 assert(def);
92 assert(def->name);
93 assert(def->instanceSize);
94 assert(def->interfaceSize);
95 assert(def->interfaceOffset);
96
97 Class *clazz = calloc(1, sizeof(Class));
98 assert(clazz);
99
100 clazz->def = *def;
101
102 clazz->interface = calloc(1, def->interfaceSize);
103 assert(clazz->interface);
104
105 Class *superclass = clazz->def.superclass;
106 if (superclass) {
107
108 assert(superclass->def.instanceSize <= def->instanceSize);
109 assert(superclass->def.interfaceSize <= def->interfaceSize);
110
111 memcpy(clazz->interface, superclass->interface, superclass->def.interfaceSize);
112 }
113
114 if (clazz->def.initialize) {
115 clazz->def.initialize(clazz);
116 }
117
118 clazz->next = __sync_lock_test_and_set(&_classes, clazz);
119
120 return clazz;
121}
static void setup(void)
Called when initializing Object to setup Objectively.
Definition Class.c:73
static Class * _classes
Definition Class.c:41
long Once
The Once type.
Definition Once.h:37
#define do_once(once, block)
Executes the given block at most one time.
Definition Once.h:43
size_t interfaceSize
The interface size (required).
Definition Class.h:79
void(* initialize)(Class *clazz)
The Class initializer (optional).
Definition Class.h:64
Class * next
Provides chaining of initialized Classes.
Definition Class.h:110
ident interface
The interface of the Class.
Definition Class.h:105

◆ classForName()

OBJECTIVELY_EXPORT Class * classForName ( const char *  name)
Returns
The Class with the given name, or NULL if no such Class has been initialized.

Definition at line 161 of file Class.c.

161 {
162
163 if (name) {
164 Class *c = _classes;
165 while (c) {
166 if (strcmp(name, c->def.name) == 0) {
167 return c;
168 }
169 c = c->next;
170 }
171
172 char *s;
173 if (asprintf(&s, "_%s", name) > 0) {
174 Class *clazz = NULL;
175#if defined(_WIN32)
176 static Once once;
177 static ident handle;
178 do_once(&once, { handle = dlopen(NULL, RTLD_LAZY); });
179 Class *(*archetype)(void) = handle ? dlsym(handle, s) : NULL;
180#else
181 Class *(*archetype)(void) = dlsym(RTLD_DEFAULT, s);
182#endif
183 if (archetype) {
184 clazz = archetype();
185 }
186
187 free(s);
188 return clazz;
189 }
190 }
191
192 return NULL;
193}
const char * name
The Class name (required).
Definition Class.h:84

◆ release()

OBJECTIVELY_EXPORT ident release ( ident  obj)

Atomically decrement the given Object's reference count. If the resulting reference count is 0, the Object is deallocated.

Returns
This function always returns NULL.

Definition at line 195 of file Class.c.

195 {
196
197 if (obj) {
198 Object *object = cast(Object, obj);
199
200 assert(object);
201
202 if (__sync_add_and_fetch(&object->referenceCount, -1) == 0) {
203 $(object, dealloc);
204 }
205 }
206
207 return NULL;
208}
static void dealloc(Object *self)
Definition Array.c:99

◆ retain()

OBJECTIVELY_EXPORT ident retain ( ident  obj)

Atomically increment the given Object's reference count.

Returns
The Object.
Remarks
By calling this, the caller is expressing ownership of the Object, and preventing it from being released. Be sure to balance calls to retain with calls to release.

Definition at line 210 of file Class.c.

210 {
211
212 Object *object = cast(Object, obj);
213
214 assert(object);
215
216 __sync_add_and_fetch(&object->referenceCount, 1);
217
218 return obj;
219}

Variable Documentation

◆ _pageSize

OBJECTIVELY_EXPORT size_t _pageSize

The page size, in bytes, of the target host.

Definition at line 154 of file Class.h.