1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
/*@@
@header OverloadMacros.h
@date Thu Feb 4 08:02:29 1999
@author Tom Goodale
@desc
Macros used for the overload functions
@enddesc
@version $Header$
@@*/
#ifndef _OVERLOADMACROS_H_
#define _OVERLOADMACROS_H_ 1
/* These are a load of macros used to make overloadable functions.
*
* Basically define ARGUMENTS with the arguments of the function,
* and RETURN_TYPE as the return type
* then put lines of the form OVERLOADABLE(function)
* in a header file.
* Defining OVERLOADABLE(name) as OVERLOADABLE_<macro>(name)
* and then including the header will create functions, prototypes
* dummy functions or some checking code as required.
*
* One must also define
*
* #define OVERLOADABLE_CALL prefix for calling overload functions
* #define OVERLOADABLE_PREFIX prefix for real functions
* #define OVERLOADABLE_DUMMY_PREFIX prefix for dummy functions
*
* to apply prefices to the functions.
*/
/* This macro defines a global variable with the name of the function
* and a function which allows people to set its value.
*
* The function can only be called twice - to set the default, and to overload it.
*/
#define OVERLOADABLE_FUNCTION(name) \
_OVERLOADABLE_FUNCTION(OVERLOADABLE_CALL,OVERLOADABLE_PREFIX, OVERLOADABLE_DUMMY_PREFIX, name)
#define _OVERLOADABLE_FUNCTION(call, prefix, dummy_prefix, name) \
__OVERLOADABLE_FUNCTION(call, prefix, dummy_prefix, name)
#define __OVERLOADABLE_FUNCTION(call, prefix, dummy_prefix, name) \
RETURN_TYPE (*prefix##name)(ARGUMENTS) = NULL; \
int call##Overload##name(RETURN_TYPE (*func)(ARGUMENTS)) \
{ \
int return_code; \
static int overloaded = 0; \
if(overloaded < 2) \
{ \
prefix##name = func; \
overloaded++; \
return_code = overloaded; \
} \
else \
{ \
char *message = malloc( (200+strlen(#name))*sizeof(char) ); \
sprintf(message, \
"Warning: Attempted to overload function %s%s twice\n",\
#prefix, #name); \
CCTK_Warn(1,__LINE__,__FILE__,"Cactus",message); \
free(message); \
return_code = 0; \
} \
\
return return_code; \
}
/* This macro creates an extern declaration for an overloadable function */
#define OVERLOADABLE_PROTOTYPE(name) _OVERLOADABLE_PROTOTYPE(OVERLOADABLE_PREFIX, OVERLOADABLE_DUMMY_PREFIX, name)
#define _OVERLOADABLE_PROTOTYPE(prefix, dummy_prefix, name) __OVERLOADABLE_PROTOTYPE(prefix, dummy_prefix, name)
#define __OVERLOADABLE_PROTOTYPE(prefix, dummy_prefix, name) \
extern RETURN_TYPE (*prefix##name)(ARGUMENTS);
/* This macro defines a dummy function */
#define OVERLOADABLE_DUMMY(name) _OVERLOADABLE_DUMMY(OVERLOADABLE_PREFIX, OVERLOADABLE_DUMMY_PREFIX, name)
#define _OVERLOADABLE_DUMMY(prefix, dummy_prefix, name) __OVERLOADABLE_DUMMY(prefix, dummy_prefix, name)
#define __OVERLOADABLE_DUMMY(prefix, dummy_prefix, name) \
RETURN_TYPE dummy_prefix##name(ARGUMENTS) \
{ \
fprintf(stderr, "Dummy %s%s called.\n", #dummy_prefix,#name); \
return 0; \
}
/* This macro defines the prototype for a dummy function. */
#define OVERLOADABLE_DUMMYPROTOTYPE(name) _OVERLOADABLE_DUMMYPROTOTYPE(OVERLOADABLE_PREFIX, OVERLOADABLE_DUMMY_PREFIX, name)
#define _OVERLOADABLE_DUMMYPROTOTYPE(prefix, dummy_prefix, name) __OVERLOADABLE_DUMMYPROTOTYPE(prefix, dummy_prefix, name)
#define __OVERLOADABLE_DUMMYPROTOTYPE(prefix, dummy_prefix, name) \
RETURN_TYPE dummy_prefix##name(ARGUMENTS);
/* This macro defines a check line which will set the overloadable
* function to be the dummy if it hasn't been set.
*/
#define OVERLOADABLE_CHECK(name) _OVERLOADABLE_CHECK(OVERLOADABLE_PREFIX, OVERLOADABLE_DUMMY_PREFIX, name)
#define _OVERLOADABLE_CHECK(prefix, dummy_prefix, name) __OVERLOADABLE_CHECK(prefix, dummy_prefix, name)
#define __OVERLOADABLE_CHECK(prefix, dummy_prefix, name) \
if(!prefix##name) prefix##name = dummy_prefix##name;
/* This macro defines the prototype for the overloading function itself */
#define OVERLOADABLE_OVERLOADPROTO(name) \
_OVERLOADABLE_OVERLOADPROTO(OVERLOADABLE_CALL,OVERLOADABLE_PREFIX, OVERLOADABLE_DUMMY_PREFIX, name)
#define _OVERLOADABLE_OVERLOADPROTO(call,prefix, dummy_prefix, name) \
__OVERLOADABLE_OVERLOADPROTO(call,prefix, dummy_prefix, name)
#define __OVERLOADABLE_OVERLOADPROTO(call,prefix, dummy_prefix, name) \
int call##Overload##name(RETURN_TYPE (*func)(ARGUMENTS));
#endif /* _OVERLOADMACROS_H_ */
|