@import("operator.felan");
@import("memory.felan");

vector :: (comptime t:type)->type{
  return struct {
    ptr : *t;
    size : u64;
    capacity : u64;
  };
};

vector_new :: (comptime t:type) -> (vector(t)) {
  v : vector(t) = undefined;
  v.ptr = malloc(0u64,@type_of(v.ptr.*));
  v.size = 0u64;
  v.capacity = 0u64;
  return v;
};

__get_item__ :: (left:*vector(anytype),index:i64) -> (@type_of(left.*.ptr.*)) {
  return (left.*.ptr + index).*;
};

__set_item__ :: (left:*vector(anytype),index:i64,item:@type_of(left.*.ptr.*)) -> (@type_of(left.*.ptr.*)) {
  return (left.*.ptr + index).* = item;
};

__get_item_address__ :: (left:*vector(anytype),index:i64) -> (@type_of(left.*.ptr)) {
  return (left.*.ptr + index);
};

push_back :: (vec:*vector(anytype),value:@type_of(vec.*[0])) -> void {
  _grow_if_needed(vec);
  vec.*[@cast(vec.*.size,i64)] = value;
  vec.*.size += 1u64;
};

_grow_if_needed :: (vec:*vector(anytype)) -> void {
  if vec.*.size == vec.*.capacity {
    vec.*.capacity = vec.*.capacity + vec.*.capacity/2u64 + 1u64;
    vec.*.ptr = realloc(vec.*.ptr,vec.*.capacity);
  }
};

delete :: (vec:vector(anytype)) -> void {
  free(vec.ptr);
};