Skip to content

joedrago/dyn

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

35 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

dyn

Everyone else has a C library for arrays, strings, and hashes. Why can't I?

Dat functionality

The best place to see all of dyn's functionality is in the header:

https://github.com/joedrago/dyn/blob/master/src/dyn.h

Example Assumptions

Assume all examples below have access to an "Object" and associated functions, such as:

typedef struct Object
{
    int a;
    int b;
} Object;
Object *createObject(...);           // allocs object, sets data from args
void destroyObject(Object *obj);     // frees obj and all member data
void destroyObjectPtr(Object **obj); // calls destroyObject on *obj, NULLs out *obj

Array Examples

Pointer array

Object **objects = NULL;
int i;
for(i = 0; i < 5; ++i)
{
    Object *obj = createObject(...);
    daPush(&objects, obj);
}
// objects[0] - objects[4] have data in them
daDestroy(&objects, destroyObjectPtr);

Integer array

int i;
int *ints = NULL;

daCreate(&ints, sizeof(int));
daPushU32(&ints, 5);
daPushU32(&ints, 7);
daPushU32(&ints, 9);
daPushU32(&ints, 11);
for(i = 0; i < daSize(&ints); ++i)
{
    printf("int %d: %d\n", i, ints[i]);
}
daDestroy(&ints, NULL);

Reuse

int i;
int *ints = NULL;

daCreate(&ints, sizeof(int));
daPushU32(&ints, 5);
daPushU32(&ints, 7);

// Destroys all elements, leaves capacity for reuse
daClear(&ints, NULL);

daPushU32(&ints, 5);
daPushU32(&ints, 7);
daDestroy(&ints, NULL);

FIFO / Stack

Object **objects = NULL;
Object *obj;
int i;
for(i = 0; i < 5; ++i)
{
    Object *obj = createObject(...);
    daPush(&objects, obj);
}
while(daShift(&objects, &obj))
{
    printf("Next item in queue: %s\n", obj->name);
    destroyObject(&obj);
}
for(i = 0; i < 5; ++i)
{
    Object *obj = createObject(...);
    daPush(&objects, obj);
}
while(daPop(&objects, &obj))
{
    printf("Next item on stack: %s\n", obj->name);
    destroyObject(&obj);
}
daDestroy(&objects, destroyObjectPtr);

Random insertion / removal

Object **objects = NULL;
daInsert(&objects, 0, createObject(...));                // equivalent to daUnshift()
daInsert(&objects, 1, createObject(...));
daInsert(&objects, daSize(&objects), createObject(...)); // equivalent to daPush()
daErase(&objects, 1, destroyObjectPtr);
daDestroy(&objects, destroyObjectPtr);

Size manipulation

int *ints = NULL;
daCreate(&ints, sizeof(int));
daSetSize(&ints, 100);       // ints should be 100 0s now
daDestroy(&ints);

Direct (Inline) storage of custom structures

int i;
struct CustomStruct
{
    int a;
    int b;
} temp, *objs = NULL;

daCreate(&objs, sizeof(struct CustomStruct));

temp.a = 5;
temp.b = 50;
daPush(&objs, temp);
temp.a = 6;
temp.b = 60;
daPush(&objs, temp);
temp.a = 7;
temp.b = 70;
daPush(&objs, temp);

for(i = 0; i < daSize(&objs); ++i)
{
    printf("int %d: %d / %d\n", i, objs[i].a, objs[i].b);
}
daDestroy(&objs, NULL);

Map Examples

Integer keys

dynMap *dm = dmCreate(DKF_INTEGER, 0);
int i;
for(i = 0; i < 5; ++i)
{
    dmGetI2I(dm, i) = i * 10;
}
for(i = 0; i < 5; ++i)
{
    printf("%d: %d\n", i, dmGetI2I(dm, i));
}
dmDestroy(dm, NULL);

String keys

dynMap *dm = dmCreate(DKF_STRING, 0);
dmGetS2P(dm, "Foo") = "A";
dmGetS2P(dm, "Bar") = "B";
dmGetS2P(dm, "Baz") = "C";
printf("Foo: %s\n", (char *)dmGetS2P(dm, "Foo"));
printf("Bar: %s\n", (char *)dmGetS2P(dm, "Bar"));
printf("Baz: %s\n", (char *)dmGetS2P(dm, "Baz"));
dmDestroy(dm, NULL);

Direct (inline) storage of custom data structures

typedef struct CustomStruct
{
    int a;
    int b;
} CustomStruct;
int i;
dynMap *dm = dmCreate(DKF_INTEGER, sizeof(CustomStruct));

for(i = 0; i < 5; ++i)
{
    CustomStruct *p = dmGetI2T(dm, CustomStruct, i);
    p->a = i * 5;
    p->b = i * 10;
}

for(i = 0; i < 5; ++i)
{
    CustomStruct *p = dmGetI2T(dm, CustomStruct, i);
    printf("entry %d: %d / %d\n", i, p->a, p->b);
}

dmDestroy(dm, NULL); // CustomStruct is freed along with the entry

String Examples

Basic usage

char *str = NULL;
dsCreate(&str);                    // Call not required; all ds*() calls lazily initialize the string
dsCopy(&str, "here is a string");   // strcpy
dsCopyLen(&str, "here is a string", 4);  // strncpy
dsPrintf(&str, "%d, %d, %d, %d, %d", 1, 2, 3, 4, 5);  // sprintf
dsConcatf(&str, "%d, %d, %d, %d, %d", 1, 2, 3, 4, 5); // sprintf + strcat

// direct manipulation
dsSetCapacity(&str, 511);
// ... use str here as if it were char str[512]
dsCalcLength(&str);                // clue in dynString that you've manually altered its data

dsDestroy(&str);                   // cleanup when you're all done (no-op on a NULL ptr)

About

Everyone else has a C library for arrays, strings, and hashes. Why can't I?

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors