test.c

J

jacob navia

#include "containers.h"
#include <stdio.h>
int testList(void)
{
List *l = newList(sizeof(double)),*l1,*l2;
double d,*pd,sum;
int isum=0,msum=0,i,errors=0;

for (i=0; i<1000;i++) {
d = i;
isum += i;
l->lpVtbl->Add(l,(void *)&d);
}
if (l->lpVtbl->GetCount(l) != 1000) {
printf("error\n");
errors++;
}
sum = 0.0;
for (i=0; i<1000;i++) {
pd = l->lpVtbl->GetElement(l,i);
sum += *pd;
}
printf ("%g %d\n",sum,isum);
sum=0;
for (i=0; i< 500;i++) {
list_element *le;
le = l->lpVtbl->Pop(l);
msum += i;
sum += *(double *)le->Data;
free(le);
}
printf ("%g %d\n",sum,msum);
if ( l->lpVtbl->GetCount(l) != 500) {
printf("error in list count\n");
errors++;
}
printf("Fisrt = %g, last =%g\n",
*(double *)l->lpVtbl->GetElement(l,0),
*(double *)l->lpVtbl->GetElement(l,499));
l1 = l->lpVtbl->GetRange(l,0,499);
if (!l->lpVtbl->Equal(l,l1))
printf("error\n"),errors++;
l2 = l->lpVtbl->Copy(l);
if (!l2->lpVtbl->Equal(l2,l1))
printf("error\n"),errors++;
for (i=0; i<l1->lpVtbl->GetCount(l); i++) {
d = *(double *)l->lpVtbl->GetElement(l,i);
if (d != i+500) {
printf("error\n");
errors++;
}
}
return errors;
}


static void PrintArrayList(ArrayList *AL)
{
int i;
printf("Count %d, Capacity %d\n",AL->count,AL->capacity);
for (i=0; i<AL->count;i++) {
printf("%s\n",AL->lpVtbl->GetElement(AL,i));
}
printf("\n");
}
int testArrayList(void)
{
int errors=0;
ArrayList *AL = newArrayList(sizeof(void *),10);
char *p;
AL->lpVtbl->Add(AL,"Martin");
AL->lpVtbl->Insert(AL,"Jakob");
if (!AL->lpVtbl->Contains(AL,"Martin")) {
printf("error, string not found!\n");
errors++;
}
printf("Count should be 2, is %d\n",AL->lpVtbl->GetCount(AL));
PrintArrayList(AL);
AL->lpVtbl->InsertAt(AL,1,"Position 1");
AL->lpVtbl->InsertAt(AL,2,"Position 2");
PrintArrayList(AL);
AL->lpVtbl->Remove(AL,"Jakob");
PrintArrayList(AL);
AL->lpVtbl->Push(AL,"pushed");
PrintArrayList(AL);
AL->lpVtbl->Pop(AL);
PrintArrayList(AL);
p = AL->lpVtbl->GetElement(AL,1);
printf("Item position 1:%s\n",p);
PrintArrayList(AL);
return errors;
}

#include <stdio.h>
static void PrintStringCollection(StringCollection *SC){
int i;
printf("Count %d, Capacity %d\n",SC->count,SC->capacity);
for (i=0; i<SC->count;i++) {
printf("%s\n",SC->lpVtbl->GetElement(SC,i));
}
printf("\n");
}
int testArrayCollection(void){
StringCollection *SC = newStringCollection(10);
char *p;
SC->lpVtbl->Add(SC,"Martin");
SC->lpVtbl->Insert(SC,"Jakob");
if (!SC->lpVtbl->Contains(SC,"Martin")) {
printf("error, string not found!\n");
}
printf("Count should be 2, is %d\n",SC->lpVtbl->GetCount(SC));
PrintStringCollection(SC);
SC->lpVtbl->InsertAt(SC,1,"Position 1");
SC->lpVtbl->InsertAt(SC,2,"Position 2");
PrintStringCollection(SC);
SC->lpVtbl->Remove(SC,"Jakob");
PrintStringCollection(SC);
SC->lpVtbl->Push(SC,"pushed");
PrintStringCollection(SC);
SC->lpVtbl->Pop(SC);
PrintStringCollection(SC);
p = SC->lpVtbl->GetElement(SC,1);
printf("Item position 1:%s\n",p);
PrintStringCollection(SC);
return 0;
}

int main(void)
{
int errors = testArrayCollection();
errors += testArrayList();
errors += testList();
return errors;
}
 
J

jacob navia

Malcolm McLean a écrit :
jacob navia said:
sum = 0.0;
for (i=0; i<1000;i++) {
pd = l->lpVtbl->GetElement(l,i);
sum += *pd;
}

Here's how ypu would do it without the container library
sum = 0.0;
for(i=0;i<N;i++)
sum += array;

you see the problem? It makes something as simple as stepping through an
array cluntsy.


Sure, why use a container when you can use an array?

There several answers to your remark.

(1) lcc-win implements operator overloading. With it, the syntax is the
same old syntax we know. In that context your remark is not valid

(2) The problem with arrays, is that if you want to insert an item
you have to do some work. This work is done for you in the arraylist container

(3) the problem with arrays is that adding items means resizing the array.
This is done for you with the arraylist container.

(4) The problem with arrays is that if you want to replace them with a list
your code needs to be changed. The container library is designed to
minimize that kind of changes and make changing a container by another
much more transparent.

But if you want to use an array (and nobody is proposing you to drop them!)
use them of course.
 
B

bartc

jacob navia said:
Malcolm McLean a écrit :
jacob navia said:
sum = 0.0;
for (i=0; i<1000;i++) {
pd = l->lpVtbl->GetElement(l,i);
sum += *pd;
}

Here's how ypu would do it without the container library
sum = 0.0;
for(i=0;i<N;i++)
sum += array;

you see the problem? It makes something as simple as stepping through an
array cluntsy.


Sure, why use a container when you can use an array?

There several answers to your remark.

(1) lcc-win implements operator overloading. With it, the syntax is the
same old syntax we know. In that context your remark is not valid


So this example is a selling point for lcc-win32, so that we don't have to
write:

pd = l->lpVtbl->GetElement(l,i);
sum += *pd;

But presumably we can also write:

sum += *(l->lpVtbl->GetElement(l,i));

I'm worried though about "l" having to appear twice (you don't notice with
this example because l is so short). Why can't we just write:

sum += *GetElement(l,i); ?

That's what people would expect when they can't use overloaded ops. To be
more precise, they would expect to write:

sum += GetElement(l,i);

(Your use of the "GetElement" name being a trifle misleading.)
 
J

jacob navia

bartc a écrit :
So this example is a selling point for lcc-win32, so that we don't have to
write:

pd = l->lpVtbl->GetElement(l,i);
sum += *pd;

But presumably we can also write:

sum += *(l->lpVtbl->GetElement(l,i));

I'm worried though about "l" having to appear twice (you don't notice with
this example because l is so short). Why can't we just write:

sum += *GetElement(l,i); ?

That's what people would expect when they can't use overloaded ops. To be
more precise, they would expect to write:

sum += GetElement(l,i);

(Your use of the "GetElement" name being a trifle misleading.)

We could have done this with simple APIs but the problem with an API like that
is that you can't change it dynamically.

Since we use function pointers, we can at any time change the API (and maintaining the
interface) with a pointer to ANOTHER function that does the same but modifies a bit the
behavior to implement feature "XYZ" not included in the existing functions.

Another point is that the name space pollution is much smaller with this
approach... I am 100% sure that many programs implement a "GetElement" function.

We would need to use a prefix like

ContainerLib_GetElement or similar.

You can (of course) define a macro

#define CLGetElement(list,index) list->lpVtbl->GetElement(list,index)

Then you write

sum += CLGetElement(l,i);
 
S

Seebs

Here's how ypu would do it without the container library
sum = 0.0;
for(i=0;i<N;i++)
sum += array;

you see the problem? It makes something as simple as stepping through an
array cluntsy.

I basically agree, although I'd point out that you could do

sum += *(l->lpVtbl->GetElement(l,i));

Jacob: No one is going to standardize a C interface which uses CamelCase.

-s
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,739
Latest member
Clint8040

Latest Threads

Top