CObject
Class.h
Go to the documentation of this file.
1 /*
2  * Copyright 2015 Brendan Bruner
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * bbruner@ualberta.ca
17  * Nov. 2015
18  */
27 #ifndef CLASS_H_
28 #define CLASS_H_
29 
30 #include <stddef.h>
31 #include <stdlib.h>
32 
33 /************************************************************************/
34 /* Bool type */
35 /************************************************************************/
36 #define CBool unsigned char
37 #define CTRUE 1
38 #define CFALSE !CTRUE
39 
40 /************************************************************************/
41 /* Configuration options */
42 /************************************************************************/
43 /*
44  * Define this to reduce the memory footprint used in .bss
45  * for error messages when an assert fails. Error messages will be much smaller,
46  * but less descriptive.
47  * 2:
48  * Error message prints line, file, and description of error,
49  * then calls assert hook.
50  * 1:
51  * Error message prints line and file of error, then calls assert
52  * failure hook.
53  * 0:
54  * No error message, only calls assert failure hook.
55  *
56  * Note, the symbol DEBUG must be defined for run time checks to be enabled.
57  * If DEBUG is not defined then asserts resolve to empty statements and the
58  * assert failure hook is never called on failed asserts.
59  */
60 #define C_DEBUG_DIAG_LEVEL 2
61 
62 /* Default memory clean up method used. */
63 /* Calling CDynamic( ) on an object will invoke this free method */
64 /* being called after destruction. */
65 /* Note, this must resolve to a method with an address in memory. */
66 /* ie, the default free method cannot be a macro function. */
67 #define CDefaultFree free
68 #define CFree CDefaultFree
69 
70 /* Default memory allocation method to use. */
71 #define CMalloc malloc
72 
73 /* Method declaration of memory free method. */
74 typedef void (*CFreeType)( void* );
75 
76 /* All classes and interfaces contain a pointer to their class */
77 /* this is the name of that pointer. */
78 #define C_CLASS _cc
79 
80 /* All classes and interfaces contain a pointer to their highest */
81 /* super class, the base object, this is the name of that pointer. */
82 #define C_ROOT _rt
83 
84 /* All classes and interfaces contain a pointer to their virtual table, */
85 /* this is the name of that pointer. */
86 #define C_VTABLE _vt
87 
88 #define C_VTABLE_OFFSET _vo
89 
90 /* These define how to print formatted strings and what to */
91 /* do when an assertion fails. */
92 #include <stdio.h>
93 #define C_PRINT( ... ) printf( __VA_ARGS__ )
94 #define C_FAILED_ASSERT_HANDLE( ) for( ;; )
95 
96 
97 /************************************************************************/
98 /* Assert Messages */
99 /************************************************************************/
100 /* Different reasons for asserting. */
101 #if C_DEBUG_DIAG_LEVEL == 2
102 
103 #define C_ASSERT_VIRTUAL_MESSAGE \
104  "Virtual method not linked. Possible causes:\n"\
105  "\t* [A0] Class constructor did not link virtual table with CVTable\n"\
106  "\t* [A1] Constructor was never called on object\n"\
107  "\t* [A2] Constructor was called, but super's constructor was not called\n"\
108  "\t* [A3] Virtual table function assignment is incomplete\n"
109 
110 #define C_ASSERT_OBJECT_MESSAGE \
111  "NULL pointer used as input\n"
112 
113 #define C_ASSERT_CAST_MESSAGE \
114  "Failure to cast object. Possible causes:\n"\
115  "\t* [C0] Did not call interface constructor, CInterface( )\n"\
116  "\t* [C1] Did not call super's constructor.\n"
117 
118 extern const char* CAssertVirtualMessage_;
119 extern const char* CAssertObjectMessage_;
120 extern const char* CAssertCastMessage_;
121 
122 #else
123 
124 #define CAssertVirtualMessage_ NULL
125 #define CAssertObjectMessage_ NULL
126 #define CAssertCastMessage_ NULL
127 
128 #endif
129 
130 
131 /************************************************************************/
132 /* Assert macros */
133 /************************************************************************/
134 #if defined( DEBUG )
135 extern void CAssert( char exp, char const* msg, char const* file, int line );
136 #else
137 #define CAssert( exp, msg, file, line ) \
138  do { \
139  (void) (exp); \
140  (void) (file); \
141  (void) (line); \
142  } while( 0 )
143 #endif
144 
145 #define C_ASSERT_VIRTUAL( method )\
146  CAssert( ((method)==NULL), CAssertVirtualMessage_, __FILE__, __LINE__ )
147 #define C_ASSERT_OBJECT( object )\
148  CAssert( ((object)==NULL), CAssertObjectMessage_, __FILE__, __LINE__ )
149 #define C_ASSERT_CAST( object, file, line )\
150  CAssert( (object) == NULL, CAssertCastMessage_, file, line )
151 
152 
153 /************************************************************************/
154 /* Base object structures */
155 /************************************************************************/
256 struct CClass
257 {
258  /* C_ROOT must be first variable in this struct. */
259  /* Do not change. */
260  void* C_ROOT;
261  size_t C_VTABLE_OFFSET;
262 };
263 
283 struct CObject
284 {
285  /* C_CLASS must be first variable in this struct. */
286  /* Do not change. */
287  struct CClass C_CLASS;
288  const void* C_VTABLE;
289  CFreeType CObject_Free;
290 };
291 
307 {
308  void (*CDestructor)( void* );
309 };
310 
322 const struct CObject_VTable* CObject_GetVTable( );
323 
336 struct CObject* CObject_Constructor( struct CObject* self );
337 
349 void CObject_Destroy( struct CObject* self );
350 
360 void CObject_SetFree( struct CObject* self, CFreeType free_method );
361 
362 /* Help macro for object construction.
363  */
364 #define CObject( self ) \
365  CObject_Constructor(self)
366 
367 /* Helper macro for object destruction.
368  */
369 #define CDestroy( mem ) \
370  CObject_Destroy((void*) (mem))
371 
372 /* Helper macro for declaring object dynamic.
373  */
374 #define CDynamic( obj ) \
375  CObject_SetFree(((struct CClass*) (obj))->C_ROOT, CDefaultFree)
376 
377 /* Helper macro for declaring free method for object.
378  */
379 #define CFreeWith( obj, freep ) \
380  CObject_SetFree(((struct CClass*) (obj))->C_ROOT, (freep))
381 
382 
383 /************************************************************************/
384 /* Base interface structures */
385 /************************************************************************/
399 {
400  /* C_CLASS must be the first member of this struct. */
401  /* Do not change. */
402  struct CClass C_CLASS;
403 };
404 
426 void CInterface( void* self, void* iface, const void* vtable );
427 
428 
429 /************************************************************************/
430 /* Helper macros for asserting and defining class methods */
431 /************************************************************************/
432 /* Asserts virtual method before calling it. */
433 #define CAssertVirtual( func )\
434  C_ASSERT_VIRTUAL(func)
435 
436 /* Helper macro for asserting pointers. */
437 #define CAssertObject( object )\
438  C_ASSERT_OBJECT((object))
439 
440 /* Cast object pointer to desired class. */
441 #if C_DEBUG_DIAG_LEVEL == 0
442 #define CCast( self_ )\
443  CObjectCast_(self_, NULL, 0)
444 #else
445 #define CCast( self_ )\
446  CObjectCast_( self_, __FILE__, __LINE__ )
447 #endif
448 
449 
450 /************************************************************************/
451 /* Casting and virtual table handling. */
452 /************************************************************************/
485 void* CObjectCast_( void* super_reference, const char* file_name, int line_num );
486 
487 
508 void CVTable( void* self, const void* vtable);
509 
542 const void* CGetVTable( void* self_ );
543 
544 
545 #endif /* CLASS_H_ */
void * CObjectCast_(void *super_reference, const char *file_name, int line_num)
Definition: Class.c:99
#define C_VTABLE
Definition: Class.h:86
void CObject_Destroy(struct CObject *self)
Definition: Class.c:107
const void * CGetVTable(void *self_)
Definition: Class.c:66
#define C_ROOT
Definition: Class.h:82
#define C_VTABLE_OFFSET
Definition: Class.h:88
Base interface.
Definition: Class.h:398
Base class.
Definition: Class.h:283
First variables in every object&#39;s memory allocation.
Definition: Class.h:256
void CObject_SetFree(struct CObject *self, CFreeType free_method)
Definition: Class.c:131
struct CObject * CObject_Constructor(struct CObject *self)
Definition: Class.c:160
CObject&#39;s virtual table declaration.
Definition: Class.h:306
void CVTable(void *self, const void *vtable)
Definition: Class.c:61