move more stuff to shared test file
This commit is contained in:
parent
86bbab90c3
commit
62751f30ab
|
|
@ -1,3 +1,5 @@
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
extern "C" fn panic() -> ! {
|
extern "C" fn panic() -> ! {
|
||||||
panic!("Called panic from external code.");
|
panic!("Called panic from external code.");
|
||||||
|
|
@ -31,10 +33,297 @@ impl MaybeFFISlice {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FFISlice {
|
impl FFISlice {
|
||||||
pub fn as_slice(&self) -> &[u8] {
|
pub unsafe fn as_slice<T: Sized>(&self) -> &[T] {
|
||||||
|
unsafe { core::slice::from_raw_parts(self.ptr.cast(), self.len) }
|
||||||
|
}
|
||||||
|
pub unsafe fn as_bytes(&self) -> &[u8] {
|
||||||
unsafe { core::slice::from_raw_parts(self.ptr, self.len) }
|
unsafe { core::slice::from_raw_parts(self.ptr, self.len) }
|
||||||
}
|
}
|
||||||
pub fn as_str(&self) -> &str {
|
pub unsafe fn as_str(&self) -> &str {
|
||||||
unsafe { core::str::from_utf8_unchecked(self.as_slice()) }
|
unsafe { core::str::from_utf8_unchecked(self.as_bytes()) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct BlobVec {
|
||||||
|
pub data: *mut u8,
|
||||||
|
pub len: usize,
|
||||||
|
pub cap: usize,
|
||||||
|
pub elem_size: usize,
|
||||||
|
pub drop: Option<extern "C" fn(*mut u8)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for BlobVec {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
data: core::ptr::null_mut(),
|
||||||
|
len: 0,
|
||||||
|
cap: 0,
|
||||||
|
elem_size: 0,
|
||||||
|
drop: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl Send for BlobVec {}
|
||||||
|
unsafe impl Sync for BlobVec {}
|
||||||
|
|
||||||
|
pub mod vec {
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
use super::ffi::*;
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
pub struct Vec<T> {
|
||||||
|
pub vec: BlobVec,
|
||||||
|
_marker: core::marker::PhantomData<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Vec<T> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self::new_with(32)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_with(capacity: usize) -> Self {
|
||||||
|
let mut vec = BlobVec {
|
||||||
|
data: core::ptr::null_mut(),
|
||||||
|
len: 0,
|
||||||
|
cap: 0,
|
||||||
|
elem_size: 0,
|
||||||
|
drop: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
extern "C" fn drop_fn<T>(ptr: *mut u8) {
|
||||||
|
unsafe {
|
||||||
|
core::ptr::drop_in_place::<T>(ptr as *mut T);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
vec_init_with(
|
||||||
|
&mut vec,
|
||||||
|
core::mem::size_of::<T>(),
|
||||||
|
Some(drop_fn::<T>),
|
||||||
|
capacity,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Self {
|
||||||
|
vec,
|
||||||
|
_marker: core::marker::PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_slice(&self) -> &[T] {
|
||||||
|
assert_eq!(self.vec.elem_size, core::mem::size_of::<T>());
|
||||||
|
unsafe { core::slice::from_raw_parts(self.vec.data as *const T, self.vec.len) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_slice_mut(&mut self) -> &mut [T] {
|
||||||
|
assert_eq!(self.vec.elem_size, core::mem::size_of::<T>());
|
||||||
|
unsafe { core::slice::from_raw_parts_mut(self.vec.data as *mut T, self.vec.len) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn push(&mut self, value: T) {
|
||||||
|
let value = core::mem::ManuallyDrop::new(value);
|
||||||
|
unsafe {
|
||||||
|
vec_push(&mut self.vec, &raw const value as *const T as *const u8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert(&mut self, value: T, index: usize) {
|
||||||
|
if index > self.vec.len {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let value = core::mem::ManuallyDrop::new(value);
|
||||||
|
unsafe {
|
||||||
|
vec_insert(
|
||||||
|
&mut self.vec,
|
||||||
|
index,
|
||||||
|
&raw const value as *const T as *const u8,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pop(&mut self) -> Option<T> {
|
||||||
|
if self.vec.len == 0 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
unsafe {
|
||||||
|
let ptr = vec_get(&mut self.vec, self.vec.len - 1) as *mut T;
|
||||||
|
let value = ptr.read();
|
||||||
|
vec_pop(&mut self.vec);
|
||||||
|
Some(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(&self, index: usize) -> Option<&T> {
|
||||||
|
if index >= self.vec.len {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
unsafe {
|
||||||
|
let ptr = vec_get(&raw const self.vec as *mut _, index) as *mut T;
|
||||||
|
Some(&*ptr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
|
||||||
|
if index >= self.vec.len {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
unsafe {
|
||||||
|
let ptr = vec_get(&raw mut self.vec, index) as *mut T;
|
||||||
|
Some(&mut *ptr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove(&mut self, index: usize) {
|
||||||
|
if index >= self.vec.len {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
unsafe {
|
||||||
|
vec_remove(&mut self.vec, index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn len(&self) -> usize {
|
||||||
|
self.vec.len
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn position<F>(&self, elem: &T, mut cmp: F) -> Option<usize>
|
||||||
|
where
|
||||||
|
F: FnMut(&T, &T) -> bool,
|
||||||
|
{
|
||||||
|
extern "C" fn cmp_trampoline<T, F: FnMut(&T, &T) -> bool>(
|
||||||
|
f: *const (),
|
||||||
|
a: *const u8,
|
||||||
|
b: *const u8,
|
||||||
|
) -> bool {
|
||||||
|
let f = unsafe { &mut *(f as *mut F) };
|
||||||
|
let a = unsafe { &*(a as *const T) };
|
||||||
|
let b = unsafe { &*(b as *const T) };
|
||||||
|
f(a, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let index = vec_find(
|
||||||
|
&raw const self.vec as *mut _,
|
||||||
|
elem as *const T as *const u8,
|
||||||
|
cmp_trampoline::<T, F>,
|
||||||
|
&raw mut cmp as *mut F as *mut (),
|
||||||
|
);
|
||||||
|
if index == usize::MAX {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn binary_search_by<F>(&self, elem: &T, mut cmp: F) -> Result<usize, usize>
|
||||||
|
where
|
||||||
|
F: FnMut(&T, &T) -> i32,
|
||||||
|
{
|
||||||
|
extern "C" fn cmp_trampoline<T, F: FnMut(&T, &T) -> i32>(
|
||||||
|
f: *const (),
|
||||||
|
a: *const u8,
|
||||||
|
b: *const u8,
|
||||||
|
) -> i32 {
|
||||||
|
let f = unsafe { &mut *(f as *mut F) };
|
||||||
|
let a = unsafe { &*(a as *const T) };
|
||||||
|
let b = unsafe { &*(b as *const T) };
|
||||||
|
f(a, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let (index, vacant) = vec_binary_search_by(
|
||||||
|
&raw const self.vec as *mut _,
|
||||||
|
elem as *const T as *const u8,
|
||||||
|
cmp_trampoline::<T, F>,
|
||||||
|
&raw mut cmp as *mut F as *mut (),
|
||||||
|
);
|
||||||
|
if vacant {
|
||||||
|
Err(index)
|
||||||
|
} else {
|
||||||
|
Ok(index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert_sorted<F>(&self, elem: T, mut cmp: F) -> Result<usize, usize>
|
||||||
|
where
|
||||||
|
F: FnMut(&T, &T) -> i32,
|
||||||
|
{
|
||||||
|
extern "C" fn cmp_trampoline<T, F: FnMut(&T, &T) -> i32>(
|
||||||
|
f: *const (),
|
||||||
|
a: *const u8,
|
||||||
|
b: *const u8,
|
||||||
|
) -> i32 {
|
||||||
|
let f = unsafe { &mut *(f as *mut F) };
|
||||||
|
let a = unsafe { &*(a as *const T) };
|
||||||
|
let b = unsafe { &*(b as *const T) };
|
||||||
|
f(a, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut elem = core::mem::ManuallyDrop::new(elem);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let (index, _inserted) = vec_insert_sorted(
|
||||||
|
&raw const self.vec as *mut _,
|
||||||
|
&raw mut elem as *const u8,
|
||||||
|
cmp_trampoline::<T, F>,
|
||||||
|
&raw mut cmp as *mut F as *mut (),
|
||||||
|
);
|
||||||
|
Ok(index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod ffi {
|
||||||
|
#![allow(improper_ctypes)]
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
unsafe extern "C" {
|
||||||
|
pub unsafe fn vec_init(
|
||||||
|
vec: *mut BlobVec,
|
||||||
|
elem_size: usize,
|
||||||
|
drop: Option<extern "C" fn(*mut u8)>,
|
||||||
|
);
|
||||||
|
pub unsafe fn vec_init_with(
|
||||||
|
vec: *mut BlobVec,
|
||||||
|
elem_size: usize,
|
||||||
|
drop: Option<extern "C" fn(*mut u8)>,
|
||||||
|
cap: usize,
|
||||||
|
);
|
||||||
|
pub unsafe fn vec_push(vec: *mut BlobVec, elem: *const u8);
|
||||||
|
pub unsafe fn vec_insert(vec: *mut BlobVec, index: usize, elem: *const u8);
|
||||||
|
pub unsafe fn vec_pop(vec: *mut BlobVec);
|
||||||
|
pub unsafe fn vec_drop_last(vec: *mut BlobVec);
|
||||||
|
pub unsafe fn vec_get(vec: *mut BlobVec, index: usize) -> *mut u8;
|
||||||
|
|
||||||
|
pub unsafe fn vec_remove(vec: *mut BlobVec, index: usize);
|
||||||
|
pub unsafe fn vec_drop(vec: *mut BlobVec);
|
||||||
|
|
||||||
|
pub unsafe fn vec_find(
|
||||||
|
vec: *mut BlobVec,
|
||||||
|
elem: *const u8,
|
||||||
|
cmp: extern "C" fn(*const (), *const u8, *const u8) -> bool,
|
||||||
|
cmp_data: *mut (),
|
||||||
|
) -> usize;
|
||||||
|
|
||||||
|
pub unsafe fn vec_binary_search_by(
|
||||||
|
vec: *mut BlobVec,
|
||||||
|
elem: *const u8,
|
||||||
|
cmp: extern "C" fn(*const (), *const u8, *const u8) -> i32,
|
||||||
|
cmp_data: *mut (),
|
||||||
|
) -> (usize, bool);
|
||||||
|
pub unsafe fn vec_insert_sorted(
|
||||||
|
vec: *mut BlobVec,
|
||||||
|
elem: *const u8,
|
||||||
|
cmp: extern "C" fn(*const (), *const u8, *const u8) -> i32,
|
||||||
|
cmp_data: *mut (),
|
||||||
|
) -> (usize, bool);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,12 +18,6 @@ impl PartialEq for Lexeme {
|
||||||
|
|
||||||
impl Eq for Lexeme {}
|
impl Eq for Lexeme {}
|
||||||
|
|
||||||
impl Lexeme {
|
|
||||||
fn lex(&self) -> &'static str {
|
|
||||||
self.1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trait AsLexeme {
|
trait AsLexeme {
|
||||||
fn as_lexeme(self) -> Option<Lexeme>;
|
fn as_lexeme(self) -> Option<Lexeme>;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,263 +1,7 @@
|
||||||
#[repr(C)]
|
#[path = "shared/shared.rs"]
|
||||||
pub struct BlobVec {
|
mod util;
|
||||||
pub data: *mut u8,
|
|
||||||
pub len: usize,
|
|
||||||
pub cap: usize,
|
|
||||||
pub elem_size: usize,
|
|
||||||
pub drop: Option<extern "C" fn(*mut u8)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct VecT<T> {
|
use util::{ffi::*, vec::Vec, BlobVec};
|
||||||
vec: BlobVec,
|
|
||||||
_marker: core::marker::PhantomData<T>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> VecT<T> {
|
|
||||||
fn new() -> Self {
|
|
||||||
Self::new_with(32)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn new_with(capacity: usize) -> Self {
|
|
||||||
let mut vec = BlobVec {
|
|
||||||
data: core::ptr::null_mut(),
|
|
||||||
len: 0,
|
|
||||||
cap: 0,
|
|
||||||
elem_size: 0,
|
|
||||||
drop: None,
|
|
||||||
};
|
|
||||||
|
|
||||||
extern "C" fn drop_fn<T>(ptr: *mut u8) {
|
|
||||||
unsafe {
|
|
||||||
core::ptr::drop_in_place::<T>(ptr as *mut T);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
vec_init_with(
|
|
||||||
&mut vec,
|
|
||||||
core::mem::size_of::<T>(),
|
|
||||||
Some(drop_fn::<T>),
|
|
||||||
capacity,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Self {
|
|
||||||
vec,
|
|
||||||
_marker: core::marker::PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_slice(&self) -> &[T] {
|
|
||||||
assert_eq!(self.vec.elem_size, core::mem::size_of::<T>());
|
|
||||||
unsafe { core::slice::from_raw_parts(self.vec.data as *const T, self.vec.len) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_slice_mut(&mut self) -> &mut [T] {
|
|
||||||
assert_eq!(self.vec.elem_size, core::mem::size_of::<T>());
|
|
||||||
unsafe { core::slice::from_raw_parts_mut(self.vec.data as *mut T, self.vec.len) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn push(&mut self, value: T) {
|
|
||||||
let value = core::mem::ManuallyDrop::new(value);
|
|
||||||
unsafe {
|
|
||||||
vec_push(&mut self.vec, &raw const value as *const T as *const u8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn insert(&mut self, value: T, index: usize) {
|
|
||||||
if index > self.vec.len {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let value = core::mem::ManuallyDrop::new(value);
|
|
||||||
unsafe {
|
|
||||||
vec_insert(
|
|
||||||
&mut self.vec,
|
|
||||||
index,
|
|
||||||
&raw const value as *const T as *const u8,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pop(&mut self) -> Option<T> {
|
|
||||||
if self.vec.len == 0 {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
unsafe {
|
|
||||||
let ptr = vec_get(&mut self.vec, self.vec.len - 1) as *mut T;
|
|
||||||
let value = ptr.read();
|
|
||||||
vec_pop(&mut self.vec);
|
|
||||||
Some(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get(&self, index: usize) -> Option<&T> {
|
|
||||||
if index >= self.vec.len {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
unsafe {
|
|
||||||
let ptr = vec_get(&raw const self.vec as *mut _, index) as *mut T;
|
|
||||||
Some(&*ptr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn get_mut(&mut self, index: usize) -> Option<&mut T> {
|
|
||||||
if index >= self.vec.len {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
unsafe {
|
|
||||||
let ptr = vec_get(&raw mut self.vec, index) as *mut T;
|
|
||||||
Some(&mut *ptr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove(&mut self, index: usize) {
|
|
||||||
if index >= self.vec.len {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
unsafe {
|
|
||||||
vec_remove(&mut self.vec, index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn len(&self) -> usize {
|
|
||||||
self.vec.len
|
|
||||||
}
|
|
||||||
|
|
||||||
fn position<F>(&self, elem: &T, mut cmp: F) -> Option<usize>
|
|
||||||
where
|
|
||||||
F: FnMut(&T, &T) -> bool,
|
|
||||||
{
|
|
||||||
extern "C" fn cmp_trampoline<T, F: FnMut(&T, &T) -> bool>(
|
|
||||||
f: *const (),
|
|
||||||
a: *const u8,
|
|
||||||
b: *const u8,
|
|
||||||
) -> bool {
|
|
||||||
let f = unsafe { &mut *(f as *mut F) };
|
|
||||||
let a = unsafe { &*(a as *const T) };
|
|
||||||
let b = unsafe { &*(b as *const T) };
|
|
||||||
f(a, b)
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
let index = vec_find(
|
|
||||||
&raw const self.vec as *mut _,
|
|
||||||
elem as *const T as *const u8,
|
|
||||||
cmp_trampoline::<T, F>,
|
|
||||||
&raw mut cmp as *mut F as *mut (),
|
|
||||||
);
|
|
||||||
if index == usize::MAX {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(index)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn binary_search_by<F>(&self, elem: &T, mut cmp: F) -> Result<usize, usize>
|
|
||||||
where
|
|
||||||
F: FnMut(&T, &T) -> i32,
|
|
||||||
{
|
|
||||||
extern "C" fn cmp_trampoline<T, F: FnMut(&T, &T) -> i32>(
|
|
||||||
f: *const (),
|
|
||||||
a: *const u8,
|
|
||||||
b: *const u8,
|
|
||||||
) -> i32 {
|
|
||||||
let f = unsafe { &mut *(f as *mut F) };
|
|
||||||
let a = unsafe { &*(a as *const T) };
|
|
||||||
let b = unsafe { &*(b as *const T) };
|
|
||||||
f(a, b)
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
let (index, vacant) = vec_binary_search_by(
|
|
||||||
&raw const self.vec as *mut _,
|
|
||||||
elem as *const T as *const u8,
|
|
||||||
cmp_trampoline::<T, F>,
|
|
||||||
&raw mut cmp as *mut F as *mut (),
|
|
||||||
);
|
|
||||||
if vacant {
|
|
||||||
Err(index)
|
|
||||||
} else {
|
|
||||||
Ok(index)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn insert_sorted<F>(&self, elem: T, mut cmp: F) -> Result<usize, usize>
|
|
||||||
where
|
|
||||||
F: FnMut(&T, &T) -> i32,
|
|
||||||
{
|
|
||||||
extern "C" fn cmp_trampoline<T, F: FnMut(&T, &T) -> i32>(
|
|
||||||
f: *const (),
|
|
||||||
a: *const u8,
|
|
||||||
b: *const u8,
|
|
||||||
) -> i32 {
|
|
||||||
let f = unsafe { &mut *(f as *mut F) };
|
|
||||||
let a = unsafe { &*(a as *const T) };
|
|
||||||
let b = unsafe { &*(b as *const T) };
|
|
||||||
f(a, b)
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut elem = core::mem::ManuallyDrop::new(elem);
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
let (index, inserted) = vec_insert_sorted(
|
|
||||||
&raw const self.vec as *mut _,
|
|
||||||
&raw const elem as *const u8,
|
|
||||||
cmp_trampoline::<T, F>,
|
|
||||||
&raw mut cmp as *mut F as *mut (),
|
|
||||||
);
|
|
||||||
Ok(index)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
|
||||||
extern "C" fn panic() -> ! {
|
|
||||||
panic!("Called panic from external code.");
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl Send for BlobVec {}
|
|
||||||
unsafe impl Sync for BlobVec {}
|
|
||||||
|
|
||||||
unsafe extern "C" {
|
|
||||||
unsafe fn vec_init(vec: *mut BlobVec, elem_size: usize, drop: Option<extern "C" fn(*mut u8)>);
|
|
||||||
unsafe fn vec_init_with(
|
|
||||||
vec: *mut BlobVec,
|
|
||||||
elem_size: usize,
|
|
||||||
drop: Option<extern "C" fn(*mut u8)>,
|
|
||||||
cap: usize,
|
|
||||||
);
|
|
||||||
unsafe fn vec_push(vec: *mut BlobVec, elem: *const u8);
|
|
||||||
unsafe fn vec_insert(vec: *mut BlobVec, index: usize, elem: *const u8);
|
|
||||||
unsafe fn vec_pop(vec: *mut BlobVec);
|
|
||||||
unsafe fn vec_drop_last(vec: *mut BlobVec);
|
|
||||||
unsafe fn vec_get(vec: *mut BlobVec, index: usize) -> *mut u8;
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
unsafe fn vec_remove(vec: *mut BlobVec, index: usize);
|
|
||||||
#[allow(dead_code)]
|
|
||||||
unsafe fn vec_drop(vec: *mut BlobVec);
|
|
||||||
|
|
||||||
unsafe fn vec_find(
|
|
||||||
vec: *mut BlobVec,
|
|
||||||
elem: *const u8,
|
|
||||||
cmp: extern "C" fn(*const (), *const u8, *const u8) -> bool,
|
|
||||||
cmp_data: *mut (),
|
|
||||||
) -> usize;
|
|
||||||
|
|
||||||
unsafe fn vec_binary_search_by(
|
|
||||||
vec: *mut BlobVec,
|
|
||||||
elem: *const u8,
|
|
||||||
cmp: extern "C" fn(*const (), *const u8, *const u8) -> i32,
|
|
||||||
cmp_data: *mut (),
|
|
||||||
) -> (usize, bool);
|
|
||||||
unsafe fn vec_insert_sorted(
|
|
||||||
vec: *mut BlobVec,
|
|
||||||
elem: *const u8,
|
|
||||||
cmp: extern "C" fn(*const (), *const u8, *const u8) -> i32,
|
|
||||||
cmp_data: *mut (),
|
|
||||||
) -> (usize, bool);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
static mut DROPS: usize = 1;
|
static mut DROPS: usize = 1;
|
||||||
|
|
@ -318,7 +62,7 @@ fn main() {
|
||||||
eprintln!("Push/pop test passed\n");
|
eprintln!("Push/pop test passed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut vec = VecT::<u32>::new_with(100);
|
let mut vec = Vec::<u32>::new_with(100);
|
||||||
assert_eq!(vec.len(), 0);
|
assert_eq!(vec.len(), 0);
|
||||||
vec.push(10);
|
vec.push(10);
|
||||||
vec.push(20);
|
vec.push(20);
|
||||||
|
|
@ -358,6 +102,6 @@ fn main() {
|
||||||
assert_eq!(vec.binary_search_by(&5, cmp), Err(0));
|
assert_eq!(vec.binary_search_by(&5, cmp), Err(0));
|
||||||
assert_eq!(vec.binary_search_by(&55, cmp), Err(4));
|
assert_eq!(vec.binary_search_by(&55, cmp), Err(4));
|
||||||
|
|
||||||
vec.insert_sorted(35, cmp);
|
_ = vec.insert_sorted(35, cmp);
|
||||||
assert_eq!(vec.as_slice(), &[20, 30, 35, 40, 50]);
|
assert_eq!(vec.as_slice(), &[20, 30, 35, 40, 50]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue