使用宏实现通用vector

vector_decl.h

#ifndef CTL_VEC_MINIMAL_SIZE
#define CTL_VEC_MINIMAL_SIZE 8
#endif
#ifndef CTL_VEC_GROW_FACTOR
#define CTL_VEC_GROW_FACTOR 2
#endif
#ifndef CTL_VEC_TRIM_RATIO
#define CTL_VEC_TRIM_RATIO 0.5
#endif

#define DECL_VEC(TYPE) \
typedef struct { \
  TYPE *data; \
  size_t begin_idx; \
  size_t size; \
  size_t capacity; \
} ctl_vec_##TYPE; \
size_t ctl_vec_##TYPE##_size(ctl_vec_##TYPE* vec); \
size_t ctl_vec_##TYPE##_begin_idx(ctl_vec_##TYPE* vec); \
int ctl_vec_##TYPE##_new(size_t size); \
void ctl_vec_##TYPE##_free(ctl_vec_##TYPE *vec); \
int ctl_vec_##TYPE##_ctor_by_size(ctl_vec_##TYPE *vec, size_t size); \
int ctl_vec_##TYPE##_ctor(ctl_vec_##TYPE *vec); \
void ctl_vec_##TYPE##_dtor(ctl_vec_##TYPE *vec); \
int ctl_vec_##TYPE##_copy(ctl_vec_##TYPE *dst, const ctl_vec_##TYPE *src); \
int ctl_vec_##TYPE##_set_at(ctl_vec_##TYPE *vec, size_t index, const TYPE data); \
int ctl_vec_##TYPE##_get_at(ctl_vec_##TYPE *vec, size_t index, TYPE* data); \
int ctl_vec_##TYPE##_push_back(ctl_vec_##TYPE *vec, const TYPE data); \
int ctl_vec_##TYPE##_pop_back(ctl_vec_##TYPE* vec, TYPE* data); \
int ctl_vec_##TYPE##_reserve(ctl_vec_##TYPE* vec, size_t new_capacity); \
int ctl_vec_##TYPE##_resize(ctl_vec_##TYPE* vec, size_t new_size); 

vector_impl.h

#define IMPL_QUAL_VEC(TYPE, QUAL) \
QUAL size_t ctl_vec_##TYPE##_size(ctl_vec_##TYPE* vec) { \
  return vec->size; \
} \
QUAL size_t ctl_vec_##TYPE##_begin_idx(ctl_vec_##TYPE* vec) { \
  return vec->begin_idx; \
} \
QUAL int ctl_vec_##TYPE##_ctor_by_size(ctl_vec_##TYPE *vec, size_t size) { \
  int code = 0; \
  TRY { \
    vec->begin_idx = 0; \
    vec->size = size; \
    vec->capacity = size; \
    vec->data = (TYPE *)malloc(vec->capacity * sizeof(TYPE)); \
    CHECK_NONULL(vec->data);           \
    /* 初始化就要初始化所有分配的内存 */  \
    for (size_t idx = 0u; idx < vec->capacity; idx++) { \
      CHECK(TYPE##_ctor(vec->data + idx)); \
    } \
  } \
  CATCH { \
    return code; \
  } \
  return 0; \
} \
QUAL int ctl_vec_##TYPE##_ctor(ctl_vec_##TYPE *vec) { \
  int code = 0; \
  TRY { \
    CHECK(ctl_vec_##TYPE##_ctor_by_size(vec, CTL_VEC_MINIMAL_SIZE)) ; \
  } CATCH { \
    return code; \
  } \
  return 0; \
} \
QUAL void ctl_vec_##TYPE##_dtor(ctl_vec_##TYPE *vec) { \
  int code = 0; \
  TRY {
    /* 销毁就要销毁所有分配的内存 */ \
    for (size_t idx = 0; idx < vec->capacity; idx++) { \
      CHECK(TYPE##_dtor(vec->data + idx)); \
    } \
    free(vec->data); \
    vec->data = NULL; \
  } CATCH { \
    return code; \
  } \
  return 0; \
} \
QUAL void ctl_vec_##TYPE##_clear(ctl_vec_##TYPE* vec) { \
  ctl_res_void res = {0}; \
  res.ec = EOK; \
  vec->begin_idx = 0U; \
  vec->size = 0U; \
  return; \
} \
QUAL int ctl_vec_##TYPE##_reserve(ctl_vec_##TYPE *vec, size_t new_capacity) { \
  int code = 0; \
  TRY {
    CHECK_NOT_EQ(new_capacity, 0); \
    if (new_capacity <= vec->capacity) { \
      return code; \
    } \
    vec->capacity = new_capacity; \
    /* 先申请内存,然后初始化 */ \
    TYPE *new_data = (TYPE *)malloc(vec->capacity * sizeof(TYPE)); \
    CHECK_NONNULL(new_data); \
    for (size_t idx = 0u; idx < vec->capacity; idx++) { \
      CHECK(TYPE##_ctor(new_data + idx)); \
    } \
    /* 把旧的内容拷贝过来 */ \
    for (size_t idx = 0; idx < vec->size; idx++) { \
      CHECK(TYPE##_copy(new_data + idx, vec->data + idx)); \
    } \
    /* 销毁掉旧的内容 */ \
    for (size_t idx = 0; idx < vec->capacity; idx++) { \
      TYPE##_dtor(vec->data + idx); \
    } \
    free(vec->data); \
    vec->data = new_data; \
  } \
  CATCH { \
    return code; \
  } \
  return 0; \
} \
QUAL int ctl_vec_##TYPE##_resize(ctl_vec_##TYPE *vec, size_t new_size) { \
  int code = 0; \
  TRY { \
    if (vec->begin_idx + new_size > vec->capacity) { \
      CHECK(ctl_vec_##TYPE##_reserve(vec, vec->begin_idx + new_size)); \
    } \
    vec->size = new_size; \
  } \
  CATCH { \
    return code; \
  } \
  return 0; \
} \
QUAL int ctl_vec_##TYPE##_copy(ctl_vec_##TYPE *dst, const ctl_vec_##TYPE *src) { \
  int code = 0;
  TRY { \
    dst->size = src->size; \
    /* 如果src的capacity已经比dst的capacity更大,那dst就要释放掉之前的内存,然后重新申请内存 */ \
    if (dst->capacity < src->size) { \
      if (dst->data) { \
        /* 释放掉dst的资源 */ \
        for (size_t idx = 0; idx < dst->capacity; idx++) { \
          TYPE##_dtor(dst->data + idx); \
        } \
        free(dst->data); \
      } \
      /* 必须要最后赋值,因为先释放后申请 */ \
      dst->capacity = src->size; \
      /* 为dst申请资源然后初始化 */ \
      dst->data = (TYPE *)malloc(dst->capacity * sizeof(TYPE)); \
      CHECK_COND_RET_RES(dst->data != NULL, EOOM, res); \
      for (size_t idx = 0; idx < src->size; idx++) { \
        CHECK_EXEC_RES_RET_RES(TYPE##_ctor(dst->data + idx), res, res); \
      } \
    } \
    dst->begin_idx = 0; \
    dst->size = src->size; \
    /* 然后拷贝 */ \
    for (size_t idx = 0; idx < src->size; idx++) { \
      CHECK(TYPE##_copy(dst->data + idx, src->data + (idx + src->begin_idx))); \
    } \
  } \
  CATCH { \
    return code; \
  } \
  return 0; \
} \
QUAL int ctl_vec_##TYPE##_get_at(ctl_vec_##TYPE *vec, size_t index, TYPE* data) { \
  int code = 0; \
  TRY { \
    CHECK_INDEX (index, vec->size); \
    CHECK(TYPE##_copy(data, vec->data + (vec->begin_idx + index))); \
  }
  CATCH { \
    return code; \
  } \
  return 0; \
} \
QUAL int ctl_vec_##TYPE##_set_at(ctl_vec_##TYPE *vec, size_t index, const TYPE value) { \
  int code = 0;
  TRY { \
    CHECK_INDEX (index, vec->size); \
    CHECK(TYPE##_copy(vec->data + (vec->begin_idx + index), &value)); \
  } \
  CATCH { \
    return code; \
  } \
  return res; \
} \
QUAL ctl_res_void ctl_vec_##TYPE##_grow(ctl_vec_##TYPE *vec) { \
  ctl_res_void res = {0}; \
  res.ec = EOK; \
  size_t new_capacity = vec->capacity * CTL_VEC_GROW_FACTOR; \
  CHECK_EXEC_RES_RET_RES(ctl_vec_##TYPE##_reserve(vec, new_capacity), res, res); \
  return res; \
} \
QUAL int ctl_vec_##TYPE##_push_back(ctl_vec_##TYPE *vec, const TYPE data) { \
  int code = 0; \
  TRY { \
    if (vec->capacity == (vec->begin_idx + vec->size)) { \
      ctl_vec_##TYPE##_grow(vec); \
    } \
    CHECK(TYPE##_copy(vec->  data + (vec->begin_idx + vec->size), &data)); \
    vec->size++; \
  } \
  CATCH { \
    return code; \
  } \
  return 0; \
} \
QUAL int ctl_vec_##TYPE##_pop_back(ctl_vec_##TYPE *vec, TYPE* data) { \
  int code = 0; \
  TRY { \
    CHECK_NOT_EQ (vec->size, 0); \
    CHECK(TYPE##_copy(&(res.value), vec-> data + (vec->begin_idx + vec->size - 1u))); \
    vec->size--; \
  } \
  CATCH { \
    return code; \
  } \
  return 0; \
}
#define IMPL_VEC(TYPE) IMPL_QUAL_VEC(TYPE, )
#define IMPL_STATIC_VEC(TYPE) IMPL_QUAL_VEC(TYPE, static)
#define IMPL_INLINE_STATIC_VEC(TYPE) IMPL_QUAL_VEC(TYPE, inline static)

如何使用 在vector.h中添加如下代码

DECL_VEC(int);

在vector.c中添加如下代码

IMPL_VEC(int);