text: /**
   * Copyright (c) 2014 rxi
   *
   * This library is free software; you can redistribute it and/or modify it
   * under the terms of the MIT license. See LICENSE for details.
   */
  
  #ifndef VEC_H
  #define VEC_H
  
  #include <stdlib.h>
  #include <string.h>
  
  #define VEC_VERSION "0.2.1"
  
  
  #define vec_unpack_(v)\
  	(char**)&(v)->data, &((v)->length), &((v)->capacity), sizeof(*(v)->data)
  
  
  #define vec_t(T)\
  	struct { T *data; unsigned int length, capacity; }
  
  
  #define vec_init(v)\
  	memset((v), 0, sizeof(*(v)))
  
  
  #define vec_deinit(v)\
  		( free((v)->data),\
  		  vec_init(v) )
  
  
  #define vec_push(v, val)\
  		( vec_expand_(vec_unpack_(v)) ? -1 :\
  		  ((v)->data[(v)->length++] = (val), 0) )
  
  
  #define vec_pop(v)\
  		(v)->data[--(v)->length]
  
  #define vec_dequeue(v) \
  		__extension__ \
  		({__typeof__(v->data[0]) tmp_ = v->data[0]; \
  		 vec_splice(v, 0, 1); \
  		 tmp_;})
  
  
  #define vec_splice(v, start, count)\
  		( vec_splice_(vec_unpack_(v), start, count),\
  		  (v)->length -= (count) )
  
  
  #define vec_swapsplice(v, start, count)\
  		( vec_swapsplice_(vec_unpack_(v), start, count),\
  		  (v)->length -= (count) )
  
  
  #define vec_insert(v, idx, val)\
  		( vec_insert_(vec_unpack_(v), idx) ? -1 :\
  		  ((v)->data[idx] = (val), 0), (v)->length++)
  
  
  #define vec_sort(v, fn)\
  		qsort((v)->data, (v)->length, sizeof(*(v)->data), fn)
  
  
  #define vec_swap(v, idx1, idx2)\
  		vec_swap_(vec_unpack_(v), idx1, idx2)
  
  
  #define vec_truncate(v, len)\
  		((v)->length = (len) < (v)->length ? (len) : (v)->length)
  
  
  #define vec_clear(v)\
  		((v)->length = 0)
  
  
  #define vec_first(v)\
  		(v)->data[0]
  
  
  #define vec_last(v)\
  		(v)->data[(v)->length - 1]
  
  
  #define vec_reserve(v, n)\
  		vec_reserve_(vec_unpack_(v), n)
  
  
  #define vec_compact(v)\
  		vec_compact_(vec_unpack_(v))
  
  
  #define vec_pusharr(v, arr, count)\
  		do {\
  			int i__, n__ = (count);\
  			if (vec_reserve_po2_(vec_unpack_(v), (v)->length + n__) != 0) break;\
  			for (i__ = 0; i__ < n__; i__++) {\
  				(v)->data[(v)->length++] = (arr)[i__];\
  			}\
  		} while (0)
  
  
  #define vec_extend(v, v2)\
  		vec_pusharr((v), (v2)->data, (v2)->length)
  
  
  #define vec_find(v, val, idx)\
  		do {\
  			for ((idx) = 0; ((unsigned int) idx) < (v)->length; (idx)++) {\
  				if ((v)->data[(idx)] == (val)) break;\
  			}\
  			if (((unsigned int) idx) == (v)->length) (idx) = -1;\
  		} while (0)
  
  
  #define vec_remove(v, val)\
  		do {\
  			int idx__;\
  			vec_find(v, val, idx__);\
  			if (idx__ != -1) vec_splice(v, idx__, 1);\
  		} while (0)
  
  
  #define vec_reverse(v)\
  		do {\
  			unsigned int i__ = (v)->length / 2;\
  			while (i__--) {\
  				vec_swap((v), i__, (v)->length - (i__ + 1));\
  			}\
  		} while (0)
  
  
  #define vec_foreach(v, var, iter)\
  		if  ( (v)->length > 0 )\
  	for ( (iter) = 0;\
  			(iter) < (v)->length && (((var) = (v)->data[(iter)]), 1);\
  			++(iter))
  
  
  #define vec_foreach_rev(v, var, iter)\
  		if  ( (v)->length > 0 )\
  	for ( (iter) = (v)->length - 1;\
  			(iter) >= 0 && (((var) = (v)->data[(iter)]), 1);\
  			--(iter))
  
  
  #define vec_foreach_ptr(v, var, iter)\
  		if  ( (v)->length > 0 )\
  	for ( (iter) = 0;\
  			(iter) < (v)->length && (((var) = &(v)->data[(iter)]), 1);\
  			++(iter))
  
  
  #define vec_foreach_ptr_rev(v, var, iter)\
  		if  ( (v)->length > 0 )\
  	for ( (iter) = (v)->length - 1;\
  			(iter) >= 0 && (((var) = &(v)->data[(iter)]), 1);\
  			--(iter))
  
  
  
  int vec_expand_(char **data, unsigned int* length, unsigned int* capacity, int memsz);
  int vec_reserve_(char **data, unsigned int* length, unsigned int* capacity, int memsz, unsigned int n);
  int vec_reserve_po2_(char **data, unsigned int* length, unsigned int* capacity, int memsz,
  			int n);
  int vec_compact_(char **data, unsigned int* length, unsigned int* capacity, int memsz);
  int vec_insert_(char **data, unsigned int* length, unsigned int* capacity, int memsz,
  		int idx);
  void vec_splice_(char **data, unsigned int* length, unsigned int* capacity, int memsz,
  		int start, int count);
  void vec_swapsplice_(char **data, unsigned int* length, unsigned int* capacity, int memsz,
  		int start, int count);
  void vec_swap_(char **data, unsigned int* length, unsigned int* capacity, int memsz,
  		int idx1, int idx2);
  
  
  typedef vec_t(void*) vec_void_t;
  typedef vec_t(char*) vec_str_t;
  typedef vec_t(int) vec_int_t;
  typedef vec_t(char) vec_char_t;
  typedef vec_t(float) vec_float_t;
  typedef vec_t(double) vec_double_t;
  
  #endif
  