/scv

ANSI C implementation of dynamic array, with interface similar to C++ std::vector

Primary LanguageCApache License 2.0Apache-2.0

Simple C Vector

Copyright 2003-2014 Joergen Ibsen

http://www.ibsensoftware.com/

scv CI codecov

About

Simple C Vector (scv) is an ANSI C implementation of a dynamic array, with an interface similar to C++ std::vector.

I wrote it for a project years ago, and decided to dust it off and make it available under the Apache License.

Usage

The include file scv.h contains documentation in the form of doxygen comments. A configuration file is included, run doxygen to generate documentation in HTML format.

You can add the source files scv.c and scv.h to your own projects.

For CI, scv uses CMake to provide an easy way to build and test across various platforms and toolsets. To create a build system for the tools on your platform, and build scv, use something along the lines of:

mkdir build
cd build
cmake ..
cmake --build .

Example

Here is an example that reads integer coordinates in the form x,y into a scv_vector and prints them in lexicographical order:

#include <stdlib.h>
#include <stdio.h>

#include "scv.h"

struct point {
	int x;
	int y;
};

int point_compare(const struct point *lhs, const struct point *rhs)
{
	if (lhs->x == rhs->x) {
		return lhs->y - rhs->y;
	}

	return lhs->x - rhs->x;
}

int main(void)
{
	struct scv_vector *v;
	struct point p;
	size_t i;

	/* create a scv_vector of points, reserving space for 10 */
	v = scv_new(sizeof p, 10);

	/* read coordinates into p and append to v */
	while (scanf("%d,%d", &p.x, &p.y) == 2) {
		scv_push_back(v, &p);
	}

	/* sort points in v */
	qsort(scv_data(v), scv_size(v), scv_objsize(v), point_compare);

	/* print points */
	for (i = 0; i < scv_size(v); ++i) {
		struct point *pp = scv_at(v, i);

		printf("%d,%d\n", pp->x, pp->y);
	}

	scv_delete(v);

	return 0;
}

Details

The user is responsible for passing pointers to valid scv_vector structures. The code contains assertions to help while debugging.

To enable the code to work in general, independent of the type of objects stored in a particular scv_vector, functions for inserting and accessing elements take and return void pointers.

This has the drawback that you cannot use a constant expression directly, but need an actual object that you can pass a pointer to, when calling functions like scv_push_back().

Pointers into the memory used to hold the elements of a scv_vector, will be valid until a function causes a reallocation. If you know the element type, and speed is important, you can use pointers to access the elements directly:

	/* v is a scv_vector of int, get a pointer to it's data */
	int *p = scv_data(v);

	/* we can access the elements of v using p */
	p[5] = 42;

scv uses malloc() for memory allocation, which works well in many cases, but if needed, you could improve performance by using a custom allocator.