Skip to content

Instantly share code, notes, and snippets.

@gofer
Last active December 16, 2015 17:26
Show Gist options
  • Select an option

  • Save gofer/db3e90b36572f249d0fc to your computer and use it in GitHub Desktop.

Select an option

Save gofer/db3e90b36572f249d0fc to your computer and use it in GitHub Desktop.
vector<long> for c89
#include <stdio.h>
#include <vector.h>
void vector_debug(vector)
struct vector *vector;
{
char delimiter = ' ';
unsigned i;
for(i = 0; i < vector->_size; ++i)
{
printf("%ld", vector->_data[i]);
if(i < vector->_size-1) putchar(delimiter);
}
putchar('\n');
}
long twice(long x) { return x << 1; }
long plus(long x, long y) { return x + y; }
void test()
{
int ret, i;
struct vector vector;
vector_init(&vector);
for(i=0; i<10; ++i)
{
ret = vector_push_back(&vector, i+1);
if(ret != 0) break;
printf("ret = %d\n", ret);
printf("vector_size(vector) = %u\n", vector_size(&vector));
printf("vector_capacity(vector) = %u\n", vector_capacity(&vector));
vector_debug(&vector);
putchar('\n');
}
printf("vector_size(vector) = %u\n", vector_size(&vector));
printf("vector_capacity(vector) = %u\n", vector_capacity(&vector));
vector_debug(&vector);
vector_map(&vector, twice);
vector_debug(&vector);
printf("vector_foldl(vector, plus) = %ld\n", vector_foldl(&vector, 0, plus));
for(i=0; i<10; ++i)
{
/*ret = vector_pop_back(&vector);
*/
ret = vector_erase(&vector, 9-i);
if(ret != 0) break;
printf("ret = %d\n", ret);
printf("vector_size(vector) = %u\n", vector_size(&vector));
printf("vector_capacity(vector) = %u\n", vector_capacity(&vector));
vector_debug(&vector);
putchar('\n');
}
vector_destroy(&vector);
}
int
main(argc, argv)
int argc;
char **argv;
{
test();
return 0;
}
#include <vector.h>
unsigned min(a, b)
unsigned a, b;
{
return a < b ? a : b;
}
int vector_init(vector)
struct vector *vector;
{
if(vector == NULL)
{
vector = (struct vector*)malloc(sizeof(struct vector));
}
vector->_capacity = INITIAL_VECTOR_SIZE;
vector->_size = 0;
vector->_data = (long*)malloc(vector->_capacity * sizeof(long));
return 0;
}
int vector_destroy(vector)
struct vector *vector;
{
if(vector != NULL)
{
free(vector->_data);
}
return 0;
}
int vector_reserve(vector, new_capacity)
struct vector *vector;
unsigned new_capacity;
{
long *ptr = (long*)malloc(sizeof(long) * new_capacity);
if(ptr == NULL) return -1;
unsigned copy_size = min(vector->_capacity, new_capacity);
vector->_data = memmove(ptr, vector->_data, sizeof(long) * copy_size);
vector->_capacity = new_capacity;
return 0;
}
int vector_push_back(vector, value)
struct vector *vector;
long value;
{
if(vector == NULL) return -1;
if(vector->_size == vector->_capacity)
{
int ret = vector_reserve(vector, vector->_capacity << 1);
if(ret != 0) return -2;
}
vector->_data[vector->_size] = value;
++vector->_size;
return 0;
}
int vector_pop_back(vector)
struct vector *vector;
{
--vector->_size;
unsigned new_capacity = vector->_capacity >> 1;
if(vector->_size <= new_capacity && new_capacity >= INITIAL_VECTOR_SIZE)
{
int ret = vector_reserve(vector, vector->_capacity >> 1);
if(ret != 0) return -1;
}
return 0;
}
int vector_erase(vector, index)
struct vector *vector;
unsigned index;
{
if(vector->_size == 0 || vector->_size <= index) return -1;
memmove(
vector->_data + (index + 0),
vector->_data + (index + 1),
(vector->_size - index) * sizeof(long)
);
--vector->_size;
unsigned new_capacity = vector->_capacity >> 1;
if(vector->_size <= new_capacity && new_capacity >= INITIAL_VECTOR_SIZE)
{
int ret = vector_reserve(vector, vector->_capacity >> 1);
if(ret != 0) return -1;
}
return 0;
}
unsigned vector_size(vector)
struct vector *vector;
{
return vector->_size;
}
unsigned vector_capacity(vector)
struct vector *vector;
{
return vector->_capacity;
}
long vector_at(vector, index)
struct vector *vector;
unsigned index;
{
if(index < vector_size(vector))
{
return vector->_data[index];
}
return 0;
}
int vector_empty(vector)
struct vector *vector;
{
return vector->_size == 0;
}
#ifndef __VECTOR_H__
#define __VECTOR_H__
#include <stdlib.h>
#include <string.h>
#define INITIAL_VECTOR_SIZE 4
/**
* Attention:
* デバッグ用にINITIAL_VECTOR_SIZEを小さくしてあるので,
* 実環境に合わせて調整する
**/
struct vector
{
unsigned _capacity;
unsigned _size;
long *_data;
};
/* vector.c */
int vector_init (struct vector*);
int vector_destroy (struct vector*);
int vector_reserve (struct vector*, unsigned);
int vector_push_back(struct vector*, long);
int vector_pop_back (struct vector*);
int vector_erase (struct vector*, unsigned);
unsigned vector_size (struct vector*);
unsigned vector_capacity (struct vector*);
long vector_at (struct vector*, unsigned);
int vector_empty (struct vector*);
/* vector_util.c */
int vector_map (struct vector*, long(*)(long));
long vector_foldl(struct vector*, long, long(*)(long, long));
#endif /* __VECTOR_H__ */
#include <vector.h>
int vector_map(vector, funcion)
struct vector *vector;
long (*funcion)(long);
{
unsigned i;
for(i = 0; i < vector->_size; ++i)
{
vector->_data[i] = funcion(vector->_data[i]);
}
return 0;
}
long vector_foldl(vector, initial, funcion)
struct vector *vector;
long initial;
long (*funcion)(long, long);
{
unsigned result = initial, i;
for(i = 0; i < vector->_size; ++i)
{
result = funcion(result, vector->_data[i]);
}
return result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment