gwenhywfar/src/base/inherit.h @ bcbec994
75083574 | aquamaniac | /***************************************************************************
|
|
$RCSfile$
|
|||
-------------------
|
|||
cvs : $Id$
|
|||
begin : Sun Dec 05 2003
|
|||
copyright : (C) 2003 by Martin Preuss
|
|||
email : martin@libchipcard.de
|
|||
***************************************************************************
|
|||
* *
|
|||
* This library is free software; you can redistribute it and/or *
|
|||
* modify it under the terms of the GNU Lesser General Public *
|
|||
* License as published by the Free Software Foundation; either *
|
|||
* version 2.1 of the License, or (at your option) any later version. *
|
|||
* *
|
|||
* This library is distributed in the hope that it will be useful, *
|
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
|||
* Lesser General Public License for more details. *
|
|||
* *
|
|||
* You should have received a copy of the GNU Lesser General Public *
|
|||
* License along with this library; if not, write to the Free Software *
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
|
|||
* MA 02111-1307 USA *
|
|||
* *
|
|||
***************************************************************************/
|
|||
#ifndef GWENHYWFAR_INHERIT_H
|
|||
#define GWENHYWFAR_INHERIT_H
|
|||
8c185d1b | aquamaniac | #ifdef __cplusplus
|
|
extern "C" {
|
|||
#endif
|
|||
75083574 | aquamaniac | typedef struct GWEN_INHERITDATA GWEN_INHERITDATA;
|
|
8c185d1b | aquamaniac | #ifdef __cplusplus
|
|
}
|
|||
#endif
|
|||
75083574 | aquamaniac | ||
#include <gwenhywfar/misc.h>
|
|||
#include <gwenhywfar/gwenhywfarapi.h>
|
|||
#ifdef __cplusplus
|
|||
extern "C" {
|
|||
#endif
|
|||
/** @defgroup GWEN_MACRO_INHERIT Macros For Typesafe Inheritance
|
|||
*
|
|||
*/
|
|||
/*@{*/
|
|||
08e008aa | martin | typedef void GWENHYWFAR_CB (*GWEN_INHERIT_FREEDATAFN)(void *baseData,
|
|
void *data);
|
|||
75083574 | aquamaniac | ||
d67aa67e | cstim | GWEN_LIST_FUNCTION_LIB_DEFS(GWEN_INHERITDATA, GWEN_InheritData, GWENHYWFAR_API)
|
|
e5b445a3 | cstim | /* No trailing semicolon because this is a macro call */
|
|
75083574 | aquamaniac | ||
e68be609 | aquamaniac | GWENHYWFAR_API
|
|
75083574 | aquamaniac | GWEN_INHERITDATA *GWEN_InheritData_new(const char *t,
|
|
GWEN_TYPE_UINT32 id,
|
|||
void *data,
|
|||
void *baseData,
|
|||
GWEN_INHERIT_FREEDATAFN fn);
|
|||
e68be609 | aquamaniac | GWENHYWFAR_API
|
|
75083574 | aquamaniac | void GWEN_InheritData_free(GWEN_INHERITDATA *d);
|
|
fb36227d | aquamaniac | GWENHYWFAR_API
|
|
void GWEN_InheritData_clear(GWEN_INHERITDATA *d);
|
|||
e68be609 | aquamaniac | GWENHYWFAR_API
|
|
75083574 | aquamaniac | const char *GWEN_InheritData_GetTypeName(const GWEN_INHERITDATA *d);
|
|
e68be609 | aquamaniac | ||
GWENHYWFAR_API
|
|||
75083574 | aquamaniac | GWEN_TYPE_UINT32 GWEN_InheritData_GetId(const GWEN_INHERITDATA *d);
|
|
e68be609 | aquamaniac | ||
GWENHYWFAR_API
|
|||
75083574 | aquamaniac | void *GWEN_InheritData_GetData(const GWEN_INHERITDATA *d);
|
|
e68be609 | aquamaniac | ||
GWENHYWFAR_API
|
|||
c9ce572e | aquamaniac | GWEN_INHERIT_FREEDATAFN
|
|
GWEN_InheritData_GetFreeDataFn(const GWEN_INHERITDATA *d);
|
|||
75083574 | aquamaniac | ||
e68be609 | aquamaniac | GWENHYWFAR_API
|
|
75083574 | aquamaniac | GWEN_TYPE_UINT32 GWEN_Inherit_MakeId(const char *typeName);
|
|
e68be609 | aquamaniac | ||
GWENHYWFAR_API
|
|||
75083574 | aquamaniac | void* GWEN_Inherit_FindData(GWEN_INHERITDATA_LIST *l,
|
|
GWEN_TYPE_UINT32 id,
|
|||
int wantCreate);
|
|||
9218c91f | aquamaniac | GWENHYWFAR_API
|
|
GWEN_INHERITDATA *GWEN_Inherit_FindEntry(GWEN_INHERITDATA_LIST *l,
|
|||
GWEN_TYPE_UINT32 id,
|
|||
int wantCreate);
|
|||
75083574 | aquamaniac | /** @name Macros To Be Used In Inherited Classes - Header Files
|
|
*
|
|||
*/
|
|||
/*@{*/
|
|||
/**
|
|||
* Use this macro inside the struct which you want to make inheritable.
|
|||
* This macro defines some new elements for the struct for administration
|
|||
* of inheritance.
|
|||
*/
|
|||
#define GWEN_INHERIT_ELEMENT(t) \
|
|||
GWEN_INHERITDATA_LIST *INHERIT__list;
|
|||
/**
|
|||
fb36227d | aquamaniac | * Use this macro in the header file of the base class. This defines
|
|
d67aa67e | cstim | * the prototypes of some inheritance functions. This macro should
|
|
* be used in libraries with the __declspec(dllexport) as the @c
|
|||
* decl argument.
|
|||
*
|
|||
* You should not care about these functions here, since you should not use
|
|||
* them directly. Please use @ref GWEN_INHERIT_GETDATA and
|
|||
* @ref GWEN_INHERIT_SETDATA instead.
|
|||
*/
|
|||
#define GWEN_INHERIT_FUNCTION_LIB_DEFS(t, decl) \
|
|||
decl void t##__INHERIT_SETDATA(t *element, \
|
|||
const char *typeName,\
|
|||
GWEN_TYPE_UINT32 id,\
|
|||
void *data,\
|
|||
GWEN_INHERIT_FREEDATAFN f);\
|
|||
decl int t##__INHERIT_ISOFTYPE(t *element, GWEN_TYPE_UINT32 id);\
|
|||
decl GWEN_INHERITDATA_LIST *t##__INHERIT_GETLIST(const t *element);\
|
|||
decl void t##__INHERIT_UNLINK(t *element, \
|
|||
const char *typeName,\
|
|||
GWEN_TYPE_UINT32 id);
|
|||
/**
|
|||
* Use this macro in the header file of the base class. This defines
|
|||
* the prototypes of some inheritance functions. This macro should
|
|||
* be used in applications, not in libraries. In libraries please
|
|||
* use the macro @ref GWEN_INHERIT_FUNCTION_LIB_DEFS.
|
|||
*
|
|||
75083574 | aquamaniac | * You should not care about these functions here, since you should not use
|
|
* them directly. Please use @ref GWEN_INHERIT_GETDATA and
|
|||
* @ref GWEN_INHERIT_SETDATA instead.
|
|||
*/
|
|||
#define GWEN_INHERIT_FUNCTION_DEFS(t) \
|
|||
d034f74b | cstim | GWEN_INHERIT_FUNCTION_LIB_DEFS(t, GWEN_DUMMY_EMPTY_ARG)
|
|
75083574 | aquamaniac | ||
/*@}*/
|
|||
/** @name Macros To Be Used In Inherited Classes - C Files
|
|||
*
|
|||
*/
|
|||
/*@{*/
|
|||
/**
|
|||
fb36227d | aquamaniac | * Use this macro in the C file of the base class. It defines the
|
|
75083574 | aquamaniac | * implementations of the inheritance functions. This macro MUST be
|
|
* placed after the include statement which includes the classes header
|
|||
* file.
|
|||
*/
|
|||
#define GWEN_INHERIT_FUNCTIONS(t) \
|
|||
GWEN_INHERITDATA_LIST *t##__INHERIT_GETLIST(const t *element) {\
|
|||
assert(element);\
|
|||
return element->INHERIT__list;\
|
|||
}\
|
|||
\
|
|||
void t##__INHERIT_SETDATA(t *element, \
|
|||
const char *typeName,\
|
|||
GWEN_TYPE_UINT32 id,\
|
|||
void *data,\
|
|||
GWEN_INHERIT_FREEDATAFN f) {\
|
|||
GWEN_INHERITDATA *d;\
|
|||
9218c91f | aquamaniac | void *p;\
|
|
fb36227d | aquamaniac | \
|
|
assert(element);\
|
|||
assert(element->INHERIT__list);\
|
|||
\
|
|||
9218c91f | aquamaniac | p=GWEN_Inherit_FindData(element->INHERIT__list, id, 1);\
|
|
if (p) {\
|
|||
fb36227d | aquamaniac | fprintf(stderr,\
|
|
"ERROR: Type \"%s\" already inherits base type\n",\
|
|||
typeName);\
|
|||
abort();\
|
|||
}\
|
|||
d=GWEN_InheritData_new(typeName, id, data, (void*)element, f);\
|
|||
GWEN_InheritData_List_Insert(d, element->INHERIT__list);\
|
|||
eb731dcb | aquamaniac | }\
|
|
\
|
|||
int t##__INHERIT_ISOFTYPE(t *element, GWEN_TYPE_UINT32 id) {\
|
|||
fb36227d | aquamaniac | assert(element);\
|
|
assert(element->INHERIT__list);\
|
|||
\
|
|||
return (GWEN_Inherit_FindData(element->INHERIT__list, id, 1)!=0);\
|
|||
}\
|
|||
eb731dcb | aquamaniac | \
|
|
fb36227d | aquamaniac | void t##__INHERIT_UNLINK(t *element, \
|
|
const char *typeName,\
|
|||
GWEN_TYPE_UINT32 id) {\
|
|||
GWEN_INHERITDATA *d;\
|
|||
\
|
|||
assert(element);\
|
|||
assert(element->INHERIT__list);\
|
|||
\
|
|||
9218c91f | aquamaniac | d=GWEN_Inherit_FindEntry(element->INHERIT__list, id, 1);\
|
|
fb36227d | aquamaniac | if (!d) {\
|
|
e3bad4aa | aquamaniac | fprintf(stderr, \
|
|
"ERROR: Type \"%s\" does not inherit base type\n",\
|
|||
fb36227d | aquamaniac | typeName);\
|
|
abort();\
|
|||
}\
|
|||
GWEN_InheritData_clear(d);\
|
|||
GWEN_InheritData_List_Del(d);\
|
|||
GWEN_InheritData_free(d);\
|
|||
75083574 | aquamaniac | }
|
|
/**
|
|||
fb36227d | aquamaniac | * Use this macro in your C file in constructor functions for the base
|
|
75083574 | aquamaniac | * class. This macro initializes the elements defined by the macro
|
|
* @ref GWEN_INHERIT_ELEMENT.
|
|||
*/
|
|||
c9ce572e | aquamaniac | #define GWEN_INHERIT_INIT(t, element) {\
|
|
assert(element);\
|
|||
element->INHERIT__list=GWEN_InheritData_List_new();\
|
|||
}
|
|||
75083574 | aquamaniac | ||
/**
|
|||
fb36227d | aquamaniac | * Use this macro in your C file in destructor functions for the base
|
|
75083574 | aquamaniac | * class. This macro deinitializes the elements defined by the macro
|
|
* @ref GWEN_INHERIT_ELEMENT. This should be the first instruction in that
|
|||
* function, because it also gives inheriting classes the opportunity to
|
|||
* free their own data associated with the given element. It causes the
|
|||
* least problems if inheriting classes free their data before the base
|
|||
* class does.
|
|||
*/
|
|||
c9ce572e | aquamaniac | #define GWEN_INHERIT_FINI(t, element) {\
|
|
assert(element);\
|
|||
GWEN_InheritData_List_free(element->INHERIT__list);\
|
|||
}
|
|||
75083574 | aquamaniac | ||
/*@}*/
|
|||
/** @name Macros To Be Used In Inheriting Classes
|
|||
*
|
|||
*/
|
|||
/*@{*/
|
|||
/**
|
|||
* Use this in the C file of inheriting classes. It initializes a global
|
|||
* variable with a hash of the inheriting type name. This is used to speed
|
|||
fb36227d | aquamaniac | * up inheritance functions. This variable will be filled with a value
|
|
75083574 | aquamaniac | * upon the first invocation of the macro @ref GWEN_INHERIT_SETDATA.
|
|
*/
|
|||
#define GWEN_INHERIT(bt, t) \
|
|||
GWEN_TYPE_UINT32 t##__INHERIT_ID=0;
|
|||
/**
|
|||
* This macros returns the private data of an inheriting class associated
|
|||
* with an element of its base class.
|
|||
*/
|
|||
#define GWEN_INHERIT_GETDATA(bt, t, element) \
|
|||
c9ce572e | aquamaniac | ((t*)GWEN_Inherit_FindData(bt##__INHERIT_GETLIST(element),t##__INHERIT_ID,0))
|
|
75083574 | aquamaniac | ||
/**
|
|||
* This macro sets the private data of an inheriting class associated
|
|||
* with an element of its base class. The last argument is a pointer to a
|
|||
* function which frees the associated data. That function will be called
|
|||
* when the element of the base class given is freed or new data is to be
|
|||
* associated with the element.
|
|||
* The prototype of that function is this:
|
|||
* @code
|
|||
* typedef void (*function)(void *baseData, void *data);
|
|||
* @endcode
|
|||
* Please note that the argument to that function is a pointer to the
|
|||
* base type element. If you want to get the private data associated with
|
|||
* the base type element (and you probably do) you must call
|
|||
* @ref GWEN_INHERIT_GETDATA.
|
|||
* Every time the macro @ref GWEN_INHERIT_SETDATA is used the previously
|
|||
* associated data will be freed by calling the function whose prototype
|
|||
* you've just learned.
|
|||
*/
|
|||
c9ce572e | aquamaniac | #define GWEN_INHERIT_SETDATA(bt, t, element, data, fn) {\
|
|
if (!t##__INHERIT_ID)\
|
|||
t##__INHERIT_ID=GWEN_Inherit_MakeId(__STRING(t));\
|
|||
bt##__INHERIT_SETDATA(element, __STRING(t), t##__INHERIT_ID, data, fn);\
|
|||
}
|
|||
75083574 | aquamaniac | ||
eb731dcb | aquamaniac | /**
|
|
* This macro checks whether the given element is of the given type.
|
|||
* @return !=0 if the pointer is of the expected type, 0 otherwise
|
|||
* @param bt base type
|
|||
* @param t derived type
|
|||
* @param element pointer which is to be checked
|
|||
*/
|
|||
#define GWEN_INHERIT_ISOFTYPE(bt, t, element) \
|
|||
((bt##__INHERIT_ISOFTYPE(element,\
|
|||
((t##__INHERIT_ID==0)?\
|
|||
((t##__INHERIT_ID=GWEN_Inherit_MakeId(__STRING(t)))):\
|
|||
t##__INHERIT_ID)))?1:0)
|
|||
fb36227d | aquamaniac | ||
/**
|
|||
* This macro gives up the inheritance for the given type. After this
|
|||
* macro has been executed there is no link left between the type and
|
|||
* its base type.
|
|||
* @param bt base type
|
|||
* @param t derived type
|
|||
*/
|
|||
#define GWEN_INHERIT_UNLINK(bt, t, element) {\
|
|||
if (!t##__INHERIT_ID)\
|
|||
t##__INHERIT_ID=GWEN_Inherit_MakeId(__STRING(t));\
|
|||
c49db899 | aquamaniac | bt##__INHERIT_UNLINK(element, __STRING(t), t##__INHERIT_ID);\
|
|
fb36227d | aquamaniac | }
|
|
75083574 | aquamaniac | /*@}*/
|
|
/*@}*/ /* defgroup */
|
|||
#ifdef __cplusplus
|
|||
}
|
|||
#endif
|
|||
#endif /* GWENHYWFAR_INHERIT_P_H */
|
|||