使用void*实现通用vector

icd函数

typedef int (ctor_func_t*)(void*);
typedef int (copy_func_t*)(void*, void*);
// 析构函数通常不返回错误码,防止嵌套错误,如果遇到错误,一般直接exit
typedef void (dtor_func_t*)(void*);

typedef struct icd_s {
  size_t size;
  ctor_func_t ctor;
  copy_func_t copy;
  dtor_func_t dtor;
} icd_t;
typedef struct vector_s {
  void *data; 
  size_t begin_idx;
  size_t size;
  size_t capacity;
  // element的icd函数
  icd_t icd;
} vector;

size_t vector_size(vector* vec) {
  return vec->size;
}
size_t vector_begin_idx(vector* vec) {
  return vec->begin_idx;
}

int vector_ctor_by_size(vector *vec, size_t size) {
  int code = 0;
  TRY {
    vec->begin_idx = 0;
    vec->size = size;
    vec->capacity = size;
    vec->data = malloc(vec->capacity * vec->icd.size);
    CHECK_NONNULL(vec->data)
    /* 初始化就要初始化所有分配的内存 */
    char* data_p = (char*)vec->data;
    for (size_t idx = 0; idx < vec->capacity; idx++) {
      CHECK(vec->icd.ctor(data_p + idx * vec->icd.size));
    }
  }
  CATCH {
    return code;
  }
  return 0;
}

void vector_dtor(vector *vec) {
  char* data_p = (char*)vec->data;
  for (size_t idx = 0; idx < vec->capacity; idx++) {
    vec->icd.dtor(data_p + idx * vec->icd.size);
  }
  free(vec->data);
  vec->data = NULL;
  return;
}

int vector_copy(vector *dst, const vector *src) {
  int code = 0;
  dst->size = src->size;
  char* dst_data_p = (char*)dst->data;
  char* src_data_p = (char*)src->data;
  TRY {
    /* 如果src的capacity已经比dst的capacity更大,那dst就要释放掉之前的内存,然后重新申请内存 */ \
    if (dst->capacity < src->size) {
      if (dst->data) {
        /* 释放掉dst的资源 */
        if (dst->icd.dtor) {
          for (size_t idx = 0u; idx < dst->capacity; idx++) {
            dst->icd.dtor(dst_data_p + idx);
          }
        }
        free(dst->data);
      }
      /* 必须要最后赋值,因为先释放后申请 */
      dst->capacity = src->size;
      /* 为dst申请资源然后初始化 */
      dst->data = malloc(dst->capacity * dst->icd.size);
      CHECK_NONULL(dst->data);
      if (dst->icd.ctor) {
        for (size_t idx = 0u; idx < src->size; idx++) {
          CHECK(dst->icd.ctor(dst_data_p + idx));
        }
      }
    }
    dst->begin_idx = 0;
    dst->size = src->size;
    /* 然后拷贝 */
    if (src->icd.copy) {
      for (size_t idx = 0u; idx < src->size; idx++) {
        CHECK(src->icd.copy(dst_data_p + idx, src_data_p + (idx + src->begin_idx))); 
      }
    }
  }
  CATCH {
    return code;
  }
  return 0;
}

void vector_clear(vector* vec) {
  vec->begin_idx = 0u;
  vec->size = 0u;
  return;
}
int vector_reserve(vector *vec, size_t new_capacity) {

  int code = 0;
  char* dst_data_p = (char*)dst->data;
  char* src_data_p = (char*)src->data;
  TRY {
    CHECK_NOT_EQ(new_capacity, 0);
    if (new_capacity <= vec->capacity) {
      return code;
    }
    vec->capacity = new_capacity;
    /* 先申请内存,然后初始化 */
    void* new_data = malloc(vec->capacity * vec->icd.size); 
    CHECK_NONNULL(new_data);
    char* new_data_p = (char*)new_data;
    if (vec->icd.ctor) {
      for (size_t idx = 0u; idx < vec->capacity; idx++) {
        CHECK(T_ctor(new_data + idx), res, res);
      }
    }
    /* 把旧的内容拷贝过来 */
    if (vec->icd.copy) {
      for (size_t idx = 0; idx < vec->size; idx++) {
        CHECK(vec->icd.copy(new_data_p + idx, data_p + idx));
      }
    }
    /* 销毁掉旧的内容 */
    if (vec->icd.dtor) {
      for (size_t idx = 0; idx < vec->capacity; idx++) {
        CHECK(vec->icd.dtor(data_p + idx));
      }
    }
    free(vec->data);
    vec->data = new_data;
  }
  CATCH {
    return code;
  }
  return 0;
}
int vector_resize(vector *vec, size_t new_size) {
  int code = 0;
  TRY {
    if (vec->begin_idx + new_size > vec->capacity) {
      CHECK(vector_reserve(vec, vec->begin_idx + new_size));
    }
    vec->size = new_size;
  } CATCH {
    return code;
  }
  return 0;
}

int vector_get_at(vector *vec, size_t index, void* elem) {
  int code = 0;
  char* data_p = (char*)vec->data;
  TRY {
    CHECK_INDEX (index, vec->size);
    memcpy(elem, data_p + index * vec->icd.size, size);
    if (vec->icd.copy)
      CHECK(vec->icd.copy(elem, data_p + index * vec->icd.size));
  }
  CATCH {
    return code;
  }
  return 0;
} 
int vector_set_at(vector *vec, size_t index, void* elem) {
  int code = 0;
  TRY {
    CHECK_INDEX (index, vec->size);
    char* data_p = (char*)vec->data;
    memcpy(data_p + index * vec->icd.size, elem, size);
    if (vec->icd.copy)
      CHECK(vec->icd.copy(data_p + index * vec->icd.size, elem));
  }
  CATCH {
    return code;
  }
  return 0;
}

int vector_grow(vector *vec) {
  int code = 0;
  size_t new_capacity = vec->capacity * CTL_VEC_GROW_FACTOR;
  TRY {
    CHECK(vector_reserve(vec, new_capacity));
  }
  CATCH {
    return code;
  }
  return 0;
}

int vector_push_back(vector *vec, const void* elem) {
  int code = 0;
  char* data_p = (char*)vec->data;
  TRY {
    if (vec->capacity == (vec->begin_idx + vec->size)) {
      CHECK(vector_grow(vec));
    }
    memcpy(vec->icd.copy(data_p + (vec->begin_idx + vec->size), elem, vec->icd.size));
    if (vec->icd.copy)
      CHECK(vec->icd.copy(data_p + (vec->begin_idx + vec->size), elem));
    vec->size++;
  }
  CATCH {
    return code;
  }
  return 0;
}
int vector_pop_back(vector *vec, void* elem) {
  int code = 0;
  TRY {
    CHECK_NOT_EQ (vec->size, 0);
    memcpy(elem, vec->icd.copy(data_p + (vec->begin_idx + vec->size), vec->icd.size));
    if (vec->icd.copy)
      CHECK(elem, vec->icd.copy(data_p + (vec->begin_idx + vec->size)));
    vec->size--;
  } CATCH {
    return code;
  }
  return 0;
}