Skip to content

NotsoanoNimus/yallic

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

yallic - Yet Another Linked List Implementation in C

No dependencies, no problems. Simple, flexible, extensible, and ready to use.

The yallic design is heavily inspired by Java's implementation (from JDK 7) of generic linked list types, with some other functions peppered in.

See the project documentation for usage information, or just thumb through the yallic.h header file. This is quite a tiny and portable library.

Pronounced as y'all-ee-see in your thickest American Southern twang. Another one out in the wild can't hurt, right?

Features

  • Simple, flexible, extensible(, (.+)ible)*.
  • Generic.
  • Well-documented.
  • Intuitive (I hope).
  • Tiny.

Why?

Since I've been ramping up my exploration of C, I need a comfortable way to use linked lists in C projects with minimal bloat or dependencies, so I figured why not roll a small library to use as needed? This library:

  1. Wraps in everything necessary to manipulate dynamic lists.
  2. Uses a single header file.
  3. Self-contains its documentation.

The project can act as a great beginner's guide to linked list operation and design too!

Usage

Using the library is fairly straightforward for most operations.

To use a rather pointless scenario:

#include <yallic.h>

#define CALLS 1000
// [...]

// Static list of values.
static size_t values[CALLS];

// Create a new linked list with a theoretically-unlimited size (UINT64_MAX).
List_t* p_linkedlist = List__new( 0 );

// Push some items onto the list, reverse it, call some function, then clear it: 1000x.
for ( size_t x = 0; x < CALLS; x++ ) {

    // Wasting CPU cycles for a joyous occasion.
    memset( &values[0], 0, CALLS*sizeof(size_t) );
    for ( size_t y = 0; y < CALLS; y++ ) {
        values[y] = y;
        List__push( p_linkedlist, &values[y] );
    }

    // Reverse the list. Flips the most-recently added node to index [0] and
    //   places the first list node at index [count(p_linkedlist)]. This uses a
    //   double-pointer because it technically organizes a wholly new list.
    //
    //   Since 1000 was the most recent push, flip the list so 0 is read up to 1000.
    List__reverse( &p_linkedlist );

    // Do something.
    __some_func_to_read_numbers_ascending( p_linkedlist );

    // Do a _shallow_ clear of the list elements. This only deletes and frees all list
    //   NODES but does NOT free the node resources which are pointed to. A _deep_ clear
    //   will attempt to free list contents and nodes alike, but leave the list ptr intact.
    //
    //   A deep clear would cause a crash here since the nodes do not point to heap data.
    List__clear_shallow( p_linkedlist );

}

// Discard the list and (shallowly) free all list nodes (but not underlying ptrs).
List__delete_shallow( &p_linkedlist );

// [...]

Unit Testing

yallic is written with a considerably large unit-test file that integrates the Criterion testing framework to make set-up, tear-down, and results displays easy to write and maintain.

If you're interested in more usage examples for the library that go beyond the Doxygen docs, just open the test file and poke around!

Compiling & Installing

It's intended to be as simple as make release; make install if you intend to use the library in multiple different projects. This will place the static library in /usr/local/lib/ and the header file in /usr/local/include/. You can then include the <yallic.h> header and link with the -lyallic flag to bring everything together in your project.

If you only want to compile the static library for linkage in a single project, just make and use the src/yallic.h and lib/libyallic.a as you wish in the target projects.

Minutiae

  • The linked lists used in this project are forward-only, meaning they are singly linked in a node chain going from the head node to where the ->next pointer is NULL. As of right now, the list does not have reverse (or "previous") pointers attached to each node, but it may be added in the future to potentially improve speeds.
  • I am aware that a List is technically different from a LinkedList -- however, I've chosen to keep the function names as they are using the List__ prefix for brevity. If someone is using this project with the intent to have dynamically-sized lists, I don't think the distinction will be necessary, and it's really just pedantic at that point.
  • I do plan to maintain and update the project and its documentation as I need to. Though I foresee this being a set-and-forget repository: if I haven't updated in a long time, rest assured the project will still work at the very least just as well as it did when I initially wrote it.

About

Yet Another Linked List Implementation in C. No dependencies, no problems.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors