Objectively 1.0.0
Ultra-lightweight object oriented framework for GNU C.
Data Structures | Macros | Functions | Variables
Class.h File Reference

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

#include <Objectively/Types.h>
#include <Objectively/Once.h>

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. More...
 
#define cast(type, obj)    ((type *) _cast(_##type(), (const ident) obj))
 Safely cast obj to type. More...
 
#define classnameof(obj)    classof(obj)->def.name
 Resolve the Class name of the given Object instance. More...
 
#define classof(obj)    ((Object *) obj)->clazz
 Resolve the Class of an Object instance. More...
 
#define interfaceof(type, clazz)    ((type##Interface *) (clazz)->interface)
 Resolve the typed interface of a Class. More...
 
#define obj
 
#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. More...
 
OBJECTIVELY_EXPORT ident _cast (Class *clazz, const ident obj)
 Perform a type-checking cast. More...
 
OBJECTIVELY_EXPORT Class_initialize (const ClassDef *clazz)
 Initializes the given Class. More...
 
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. More...
 
OBJECTIVELY_EXPORT ident retain (ident obj)
 Atomically increment the given Object's reference count. More...
 

Variables

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

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 159 of file Class.h.

◆ cast

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

Safely cast obj to type.

Definition at line 165 of file Class.h.

◆ classnameof

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

Resolve the Class name of the given Object instance.

Definition at line 177 of file Class.h.

◆ classof

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

Resolve the Class of an Object instance.

Definition at line 171 of file Class.h.

◆ interfaceof

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

Resolve the typed interface of a Class.

Definition at line 183 of file Class.h.

◆ obj

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

◆ 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__); \
})
#define type

Function Documentation

◆ _alloc()

OBJECTIVELY_EXPORT ident _alloc ( Class clazz)

Instantiate a type through the given Class.

Definition at line 128 of file Class.c.

128 {
129
130 ident obj = calloc(1, clazz->def.instanceSize);
131 assert(obj);
132
133 Object *object = (Object *) obj;
134
135 object->clazz = clazz;
136 object->referenceCount = 1;
137
138 ident interface = clazz->interface;
139 do {
140 *(ident *) (obj + clazz->def.interfaceOffset) = interface;
141 } while ((clazz = clazz->def.superclass));
142
143 return obj;
144}
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

◆ _cast()

OBJECTIVELY_EXPORT ident _cast ( Class clazz,
const ident  obj 
)

Perform a type-checking cast.

Definition at line 146 of file Class.c.

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

◆ _initialize()

OBJECTIVELY_EXPORT Class * _initialize ( const ClassDef clazz)

Initializes the given Class.

Parameters
clazzThe Class descriptor.
Returns
The initialized Class.

Definition at line 91 of file Class.c.

91 {
92
93 static Once once;
94 do_once(&once, setup());
95
96 assert(def);
97 assert(def->name);
98 assert(def->instanceSize);
99 assert(def->interfaceSize);
100 assert(def->interfaceOffset);
101
102 Class *clazz = calloc(1, sizeof(Class));
103 assert(clazz);
104
105 clazz->def = *def;
106
107 clazz->interface = calloc(1, def->interfaceSize);
108 assert(clazz->interface);
109
110 Class *superclass = clazz->def.superclass;
111 if (superclass) {
112
113 assert(superclass->def.instanceSize <= def->instanceSize);
114 assert(superclass->def.interfaceSize <= def->interfaceSize);
115
116 memcpy(clazz->interface, superclass->interface, superclass->def.interfaceSize);
117 }
118
119 if (clazz->def.initialize) {
120 clazz->def.initialize(clazz);
121 }
122
123 clazz->next = __sync_lock_test_and_set(&_classes, clazz);
124
125 return clazz;
126}
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
void setup(URLSessionTask *)
Sets up this task.

◆ 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 165 of file Class.c.

165 {
166
167 if (name) {
168 Class *c = _classes;
169 while (c) {
170 if (strcmp(name, c->def.name) == 0) {
171 return c;
172 }
173 c = c->next;
174 }
175
176 char *s;
177 if (asprintf(&s, "_%s", name) > 0) {
178 static Once once;
179
180 do_once(&once, _handle = dlopen(NULL, 0));
181
182 Class *clazz = NULL;
183 Class *(*archetype)(void) = dlsym(_handle, s);
184 if (archetype) {
185 clazz = archetype();
186 }
187
188 free(s);
189 return clazz;
190 }
191 }
192
193 return NULL;
194}
static ident _handle
Definition: Class.c:42
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 196 of file Class.c.

196 {
197
198 if (obj) {
199 Object *object = cast(Object, obj);
200
201 assert(object);
202
203 if (__sync_add_and_fetch(&object->referenceCount, -1) == 0) {
204 $(object, dealloc);
205 }
206 }
207
208 return NULL;
209}
#define cast(type, obj)
Safely cast obj to type.
Definition: Class.h:165
void dealloc(Object *self)
Frees all resources held by this Object.
Definition: Array.c:50

◆ 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 211 of file Class.c.

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

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.