J
jacob navia
When I presented an example of the interface here (thread CCL vs STL, a
comparison), many posters complained about the syntax:
int main(void)
{
List *L;
int data;
L = iList.Create(sizeof(int));
data = 0;
iList.Add(L,&data);
iList.PushFront(L,&data);
data = 2;
iList.InsertAt(L,1,&data);
// ...
}
It was said that passing a void pointer couldn't be checked by
the compiler (what is trure of course) and that the whole wasn't
very easy to use (maybe).
I have developed a "generic" approach using a parametized file.
For instance, if you want a list of integers, you write a small file
like this:
---------------------------intlist.c (the implementation)
#include "containers.h"
#undef DATA_TYPE
#define DATA_TYPE int
#include "listgen.c"
#undef DATA_TYPE
----------------------------intlist.h (the declarations)
#include "containers.h"
#undef DATA_TYPE
#define DATA_TYPE int
#include "listgen.h"
#undef DATA_TYPE
That's all. This defines following stuff:
A type called "intList" that implements ALL the functions
of the list container for the int data type. The requirements
for the data type are that it must be a value type, i.e. the
code assumes that it is passed by value. At the same time
the "iintList" interface is defined with the same entry
points as the generic list interface iList.
Besides it must be a single token, for instance for using
long long you must
typedef long long longlong;
#define DATA_TYPE longlong
Besides those two points, the file allows now to do as follows:
-------------------------------using specialized list container
#include "containers.h"
#include "intlist.h"
static int PrintInt(int data,void *extraArgs)
{
fprintf(extraArgs,"%d ",data);
}
int main(void)
{
intList *L;
int data;
L = iintList.Create(sizeof(int));
iintList.Add(L,0);
iintList.PushFront(L,0);
iintList.InsertAt(L,1,2);
iintList.Add(L,5);
iintList.Add(L,6);
iintList.Apply(L,PrintInt,stdout);
iintList.Finalize(L);
}
Note that the "Create" function still takes the same
arguments as the original generic one. I want to keep
all code compatible since it would be better to avoid code bloat.
Each instanstiated type adds 18.6K to the program (x86+gcc/OS X Mac)
If you have several types, code could be shared in many instances
since the data type remains compatible, and the signatures weren't
changed.
For the time being code is NOT shared.
What do you think?
jacob
comparison), many posters complained about the syntax:
int main(void)
{
List *L;
int data;
L = iList.Create(sizeof(int));
data = 0;
iList.Add(L,&data);
iList.PushFront(L,&data);
data = 2;
iList.InsertAt(L,1,&data);
// ...
}
It was said that passing a void pointer couldn't be checked by
the compiler (what is trure of course) and that the whole wasn't
very easy to use (maybe).
I have developed a "generic" approach using a parametized file.
For instance, if you want a list of integers, you write a small file
like this:
---------------------------intlist.c (the implementation)
#include "containers.h"
#undef DATA_TYPE
#define DATA_TYPE int
#include "listgen.c"
#undef DATA_TYPE
----------------------------intlist.h (the declarations)
#include "containers.h"
#undef DATA_TYPE
#define DATA_TYPE int
#include "listgen.h"
#undef DATA_TYPE
That's all. This defines following stuff:
A type called "intList" that implements ALL the functions
of the list container for the int data type. The requirements
for the data type are that it must be a value type, i.e. the
code assumes that it is passed by value. At the same time
the "iintList" interface is defined with the same entry
points as the generic list interface iList.
Besides it must be a single token, for instance for using
long long you must
typedef long long longlong;
#define DATA_TYPE longlong
Besides those two points, the file allows now to do as follows:
-------------------------------using specialized list container
#include "containers.h"
#include "intlist.h"
static int PrintInt(int data,void *extraArgs)
{
fprintf(extraArgs,"%d ",data);
}
int main(void)
{
intList *L;
int data;
L = iintList.Create(sizeof(int));
iintList.Add(L,0);
iintList.PushFront(L,0);
iintList.InsertAt(L,1,2);
iintList.Add(L,5);
iintList.Add(L,6);
iintList.Apply(L,PrintInt,stdout);
iintList.Finalize(L);
}
Note that the "Create" function still takes the same
arguments as the original generic one. I want to keep
all code compatible since it would be better to avoid code bloat.
Each instanstiated type adds 18.6K to the program (x86+gcc/OS X Mac)
If you have several types, code could be shared in many instances
since the data type remains compatible, and the signatures weren't
changed.
For the time being code is NOT shared.
What do you think?
jacob