Just for fun...

Just for fun I decided to try and write a typeless doubly-linked list in C (I will also use it if I manage to do this). Disch put me on to the idea in this post: http://cplusplus.com/forum/articles/31828/#msg172251

I'm just doing this for the sake of doing something I probably shouldn't be able to do.

I've got the templates (pun intended) for a way of defining linkedlists to work with any type already:
linkedlist.h
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
#ifndef _LINKEDLIST_H
#define _LINKEDLIST_H

/**
 * \brief	Generate the name of a linkedlist node structure
 * \param TYPE	Data type that the list will store
 */
#define linkedlist_struct(TYPE)	struct TYPE##_linkedlist 

/**
 * \brief	Create a linkedlist node structure
 * \param TYPE	Data type that the list will store
 * \example
 *	An integer node
 *		linkedlist_define_struct(int);
 *	Which expands to
 *		struct int_linkedlist {
 *			int			data;
 *			struct int_linkedlist*	prev;
 *			struct int_linkedlist*	next;
 *			
 *		};
 */
#define linkedlist_define_struct(TYPE)			\
	linkedlist_struct(TYPE) {			\
		TYPE				data;	\
		linkedlist_struct(TYPE)*	prev;	\
		linkedlist_struct(TYPE)*	next;	\
	}

/*
 * \brief Declare/define a function 
 * \param TYPE	Function data type (e.g. int, float, char*)
 * \param NAME	Function name (e.g. add_node, remove_node)
 * \param ...	List of function arguments
 * \example
 *	A function to add a node to a linkedlist of integers
 *		linkedlist_function(int, add_node, int data)
 *		{
 *			linkedlist_struct(int) node =
 *					malloc(sizeof(linkedlist_struct(int)));
 *			(*node) = (linkedlist_struct(int)) {
 *				.data = data,
 *				.prev = list,
 *				.next = NULL
 *			};
 *			list->next = node;
 *			list = node;
 *		}
 *	Which expands to
 *		struct int_linkedlist* int_add_node(int data)
 *		{
 *			struct int_linkedlist* node =
 *					malloc(sizeof(struct int_linkedlist));
 *			(*node) = (struct int_linkedlist) {
 *				.data = data,
 *				.prev = list,
 *				.next = NULL
 *			};
 *			list->next = node;
 *			list = node;
 *		}
 */
#define linkedlist_function(TYPE, NAME, ...)		\
	linkedlist_struct(TYPE)	TYPE##_##NAME(__VA_ARGS__)

/**
 * \brief	Call a function
 * \param TYPE	Function data type (e.g. int, float, char*)
 * \param NAME	Function name (e.g. add_node, remove_node)
 * \param ...	List of arguments to pass to the function
 * \example
 *	Calling a function to add a node to a list of integers
 *		call_linkedlist_function(int, add_node, mydata);
 *	Which expands to
 *		int_add_node(mydata);
 */
#define call_linkedlist_function(TYPE, NAME, ...) TYPE##_##NAME(__VA_ARGS__)

#endif /* ! _LINKEDLIST_H */ 

but that takes all of the fun out of this.

Thoughts? Suggestions?

NB: Excuse any mistakes made due to absence-of-mind, I wrote this code rather hurriedly.
Last edited on
I've just noticed a pretty big hole in my plan - if you pass a pointer (e.g. char*) for TYPE, the macro won't work properly (linkedlist_struct(char*), for example, becomes struct char*_linkedlist; which is illegal).

Any ideas of how I can fix that (aside from disallowing pointers as types, that's not really an option).
Last edited on
As far as I know, you can't fix it. What's wrong with templates again?
I guess you should read this: http://www.cplusplus.com/forum/general/15251/
I prefer to use the gnu extensions for this stuff.
@PiMaster,
I could, but it would be complicated (unless I cheat). As for templates, I'm working in C.

@Bazzy,
That's rather helpful, thanks :)

@rocketboy9000,
I can't since I'd like it to work on other compilers.
Topic archived. No new replies allowed.