I'm trying to achieve method overloading in C, preferably using macros so the header/library can handle the definitions and declarations instead of putting that onto the user. Now I've read this answer about using _Generic
however the problem is my functions have struct
types. So there's no way to evaluate their type using a __typeof__
of _Generic
. I wonder if there is any way at all.
This is how my header file looks like (which is all we should be concerned with)-
#pragma once
// Macros for generic like use of the data structure
// Macros for the stack type itself
/*
* Define stack with corresponding type
* Converts Stack(int) to intstack_t
*/
#define Stack(type) type stack_t
// Macros for functions
/*
* Define createStack function
* Converts createStack(int, 5) to create_intstack(5)
*/
#define createStack(type, capacity) create_ ##type ##stack(capacity)
/*
* Define destroyStack function
* Converts destroyStack(someIntStack) to destroy_intstack(someIntStack)
* Where someIntStack is a pointer to a variable of type intstack_t
*/
#define destroyStack(stack) _Generic(stack, intstack_t*: destroy_intstack, charstack_t*: destroy_charstack)(stack)
/*
* Define push function
* Converts push(someIntStack, data) to intstack_push(someIntStack, data)
* Where someIntStack is a pointer to a variable of type intstack_t
*/
#define push(stack, data) _Generic(stack, intstack_t*: intstack_push, charstack_t*: charstack_push)(stack, data)
// Stack structure definition(s)
// int stack definition
typedef struct IntegerStack {
int top;
unsigned capacity;
int* arr;
}intstack_t;
// char stack definition
typedef struct CharacterStack {
int top;
unsigned capacity;
char* arr;
}charstack_t;
//Stack functions
// int stack functions
intstack_t* create_intstack(int);
void destroy_intstack(intstack_t*);
void intstack_push(intstack_t*, int);
// char stack functions
charstack_t* create_charstack(int);
void destroy_charstack(charstack_t*);
void charstack_push(charstack_t*, char);
Majority of the function declarations (and indirectly, their respective macros) have been removed, as they all essentially function the same. I'm only concerned about the push
function macro as provided. The other macros are really there to show what kind of usecase I intend. Obviously the macro used in push
using _Generic
will not work as intstack_t
or charstack_t
are not primitive types.
The goal is for the user to be able to use push(stack, data)
where the stack can be a variable of either type intstack_t*
or charstack_t*
and the statement push(stack, data)
will be transformed into intstack_push(stack, data)
or charstack_push(stack, data)
respectively.