1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#![allow(incomplete_features)]
#![feature(const_extern_fn)]
#![feature(const_generics)]
#![feature(const_raw_ptr_deref)]

use staticvec::StaticVec;

#[cfg(feature = "capacity_16")]
pub const VECTOR_CAPACITY: usize = 16;

#[cfg(feature = "capacity_32")]
pub const VECTOR_CAPACITY: usize = 32;

#[cfg(feature = "capacity_64")]
pub const VECTOR_CAPACITY: usize = 64;

#[cfg(feature = "capacity_128")]
pub const VECTOR_CAPACITY: usize = 128;

#[cfg(feature = "capacity_256")]
pub const VECTOR_CAPACITY: usize = 256;

#[cfg(feature = "capacity_512")]
pub const VECTOR_CAPACITY: usize = 512;

pub type VoidPtr = *const core::ffi::c_void;

// TODO: Figure out if there's any possible way to accept more than
// just opaque pointers.
pub type CStaticVec = StaticVec<VoidPtr, VECTOR_CAPACITY>;

// TODO: Maybe make this an actual union or something? Might not be worth
// it though.
#[repr(C)]
pub struct COption {
  is_some: bool,
  value: VoidPtr,
}

#[no_mangle]
pub const unsafe extern "C" fn staticvec_capacity(vec: *const CStaticVec) -> usize {
  (*vec).capacity()
}

#[no_mangle]
pub unsafe extern "C" fn staticvec_clear(vec: *mut CStaticVec) {
  (*vec).clear();
}

#[no_mangle]
pub unsafe extern "C" fn staticvec_contains(vec: *const CStaticVec, item: VoidPtr) -> bool {
  (*vec).contains(&item)
}

#[no_mangle]
pub unsafe extern "C" fn staticvec_get(vec: *const CStaticVec, index: usize) -> VoidPtr {
  (*vec)[index]
}

#[no_mangle]
pub unsafe extern "C" fn staticvec_insert(vec: *mut CStaticVec, index: usize, item: VoidPtr) {
  (*vec).insert(index, item);
}

#[no_mangle]
pub const unsafe extern "C" fn staticvec_len(vec: *const CStaticVec) -> usize {
  (*vec).len()
}

#[no_mangle]
pub const extern "C" fn staticvec_new() -> CStaticVec {
  StaticVec::new()
}

#[no_mangle]
pub const extern "C" fn staticvec_new_from_const_array(values: [VoidPtr; VECTOR_CAPACITY]) -> CStaticVec {
  StaticVec::new_from_const_array(values)
}

#[no_mangle]
pub unsafe extern "C" fn staticvec_pop(vec: *mut CStaticVec) -> COption {
  let res = (*vec).pop();
  if res.is_some() {
    COption {
      is_some: true,
      value: res.unwrap(),
    }
  } else {
    COption {
      is_some: false,
      value: core::ptr::null(),
    }
  }
}

#[no_mangle]
pub unsafe extern "C" fn staticvec_push(vec: *mut CStaticVec, item: VoidPtr) {
  (*vec).push(item);
}

#[no_mangle]
pub const unsafe extern "C" fn staticvec_remaining_capacity(vec: *const CStaticVec) -> usize {
  (*vec).remaining_capacity()
}

#[no_mangle]
pub unsafe extern "C" fn staticvec_remove(vec: *mut CStaticVec, index: usize) -> VoidPtr {
  (*vec).remove(index)
}

#[no_mangle]
pub unsafe extern "C" fn staticvec_remove_item(vec: *mut CStaticVec, item: VoidPtr) -> COption {
  let res = (*vec).remove_item(&item);
  if res.is_some() {
    COption {
      is_some: true,
      value: res.unwrap(),
    }
  } else {
    COption {
      is_some: false,
      value: core::ptr::null(),
    }
  }
}

#[no_mangle]
pub unsafe extern "C" fn staticvec_set(vec: *mut CStaticVec, index: usize, item: VoidPtr) {
  (*vec)[index] = item
}

#[no_mangle]
pub const unsafe extern "C" fn staticvec_size_in_bytes(vec: *const CStaticVec) -> usize {
  (*vec).size_in_bytes()
}