|
/***************************************************************************
|
|
$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
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
typedef struct GWEN_INHERITDATA GWEN_INHERITDATA;
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
|
|
#include <gwenhywfar/misc.h>
|
|
#include <gwenhywfar/gwenhywfarapi.h>
|
|
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
|
|
/** @defgroup GWEN_MACRO_INHERIT Macros For Typesafe Inheritance
|
|
*
|
|
*/
|
|
/*@{*/
|
|
typedef void GWENHYWFAR_CB (*GWEN_INHERIT_FREEDATAFN)(void *baseData,
|
|
void *data);
|
|
|
|
GWEN_LIST_FUNCTION_LIB_DEFS(GWEN_INHERITDATA, GWEN_InheritData, GWENHYWFAR_API)
|
|
/* No trailing semicolon because this is a macro call */
|
|
|
|
GWENHYWFAR_API
|
|
GWEN_INHERITDATA *GWEN_InheritData_new(const char *t,
|
|
GWEN_TYPE_UINT32 id,
|
|
void *data,
|
|
void *baseData,
|
|
GWEN_INHERIT_FREEDATAFN fn);
|
|
GWENHYWFAR_API
|
|
void GWEN_InheritData_free(GWEN_INHERITDATA *d);
|
|
|
|
GWENHYWFAR_API
|
|
void GWEN_InheritData_clear(GWEN_INHERITDATA *d);
|
|
|
|
GWENHYWFAR_API
|
|
const char *GWEN_InheritData_GetTypeName(const GWEN_INHERITDATA *d);
|
|
|
|
GWENHYWFAR_API
|
|
GWEN_TYPE_UINT32 GWEN_InheritData_GetId(const GWEN_INHERITDATA *d);
|
|
|
|
GWENHYWFAR_API
|
|
void *GWEN_InheritData_GetData(const GWEN_INHERITDATA *d);
|
|
|
|
GWENHYWFAR_API
|
|
GWEN_INHERIT_FREEDATAFN
|
|
GWEN_InheritData_GetFreeDataFn(const GWEN_INHERITDATA *d);
|
|
|
|
GWENHYWFAR_API
|
|
GWEN_TYPE_UINT32 GWEN_Inherit_MakeId(const char *typeName);
|
|
|
|
GWENHYWFAR_API
|
|
void* GWEN_Inherit_FindData(GWEN_INHERITDATA_LIST *l,
|
|
GWEN_TYPE_UINT32 id,
|
|
int wantCreate);
|
|
|
|
GWENHYWFAR_API
|
|
GWEN_INHERITDATA *GWEN_Inherit_FindEntry(GWEN_INHERITDATA_LIST *l,
|
|
GWEN_TYPE_UINT32 id,
|
|
int wantCreate);
|
|
|
|
/** @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;
|
|
|
|
/**
|
|
* 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 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.
|
|
*
|
|
* 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) \
|
|
GWEN_INHERIT_FUNCTION_LIB_DEFS(t, GWEN_DUMMY_EMPTY_ARG)
|
|
|
|
/*@}*/
|
|
|
|
|
|
/** @name Macros To Be Used In Inherited Classes - C Files
|
|
*
|
|
*/
|
|
/*@{*/
|
|
/**
|
|
* Use this macro in the C file of the base class. It defines the
|
|
* 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;\
|
|
void *p;\
|
|
\
|
|
assert(element);\
|
|
assert(element->INHERIT__list);\
|
|
\
|
|
p=GWEN_Inherit_FindData(element->INHERIT__list, id, 1);\
|
|
if (p) {\
|
|
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);\
|
|
}\
|
|
\
|
|
int t##__INHERIT_ISOFTYPE(t *element, GWEN_TYPE_UINT32 id) {\
|
|
assert(element);\
|
|
assert(element->INHERIT__list);\
|
|
\
|
|
return (GWEN_Inherit_FindData(element->INHERIT__list, id, 1)!=0);\
|
|
}\
|
|
\
|
|
void t##__INHERIT_UNLINK(t *element, \
|
|
const char *typeName,\
|
|
GWEN_TYPE_UINT32 id) {\
|
|
GWEN_INHERITDATA *d;\
|
|
\
|
|
assert(element);\
|
|
assert(element->INHERIT__list);\
|
|
\
|
|
d=GWEN_Inherit_FindEntry(element->INHERIT__list, id, 1);\
|
|
if (!d) {\
|
|
fprintf(stderr, \
|
|
"ERROR: Type \"%s\" does not inherit base type\n",\
|
|
typeName);\
|
|
abort();\
|
|
}\
|
|
GWEN_InheritData_clear(d);\
|
|
GWEN_InheritData_List_Del(d);\
|
|
GWEN_InheritData_free(d);\
|
|
}
|
|
|
|
/**
|
|
* Use this macro in your C file in constructor functions for the base
|
|
* class. This macro initializes the elements defined by the macro
|
|
* @ref GWEN_INHERIT_ELEMENT.
|
|
*/
|
|
#define GWEN_INHERIT_INIT(t, element) {\
|
|
assert(element);\
|
|
element->INHERIT__list=GWEN_InheritData_List_new();\
|
|
}
|
|
|
|
|
|
/**
|
|
* Use this macro in your C file in destructor functions for the base
|
|
* 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.
|
|
*/
|
|
#define GWEN_INHERIT_FINI(t, element) {\
|
|
assert(element);\
|
|
GWEN_InheritData_List_free(element->INHERIT__list);\
|
|
}
|
|
|
|
/*@}*/
|
|
|
|
/** @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
|
|
* up inheritance functions. This variable will be filled with a value
|
|
* 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) \
|
|
((t*)GWEN_Inherit_FindData(bt##__INHERIT_GETLIST(element),t##__INHERIT_ID,0))
|
|
|
|
/**
|
|
* 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.
|
|
*/
|
|
#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);\
|
|
}
|
|
|
|
/**
|
|
* 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)
|
|
|
|
/**
|
|
* 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));\
|
|
bt##__INHERIT_UNLINK(element, __STRING(t), t##__INHERIT_ID);\
|
|
}
|
|
|
|
/*@}*/
|
|
|
|
/*@}*/ /* defgroup */
|
|
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
#endif /* GWENHYWFAR_INHERIT_P_H */
|
|
|
|
|
|
|