use std::{ptr, slice};
use std::marker::PhantomData;
use std::ops::{Index, IndexMut};
#[repr(C)]
#[derive(Clone, Copy)]
pub struct CSlice<'a, T> {
base: *const T,
len: usize,
marker: PhantomData<&'a ()>
}
impl<'a, T> CSlice<'a, T> {
pub unsafe fn new(base: *const T, len: usize) -> Self {
assert!(base != ptr::null());
CSlice {
base: base,
len: len,
marker: PhantomData
}
}
pub fn as_ptr(&self) -> *const T {
self.base
}
pub fn len(&self) -> usize {
self.len
}
}
impl<'a, T> AsRef<[T]> for CSlice<'a, T> {
fn as_ref(&self) -> &[T] {
unsafe {
slice::from_raw_parts(self.base, self.len)
}
}
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct CMutSlice<'a, T> {
base: *mut T,
len: usize,
marker: PhantomData<&'a ()>
}
impl<'a, T> CMutSlice<'a, T> {
pub unsafe fn new(base: *mut T, len: usize) -> Self {
assert!(base != ptr::null_mut());
CMutSlice {
base: base,
len: len,
marker: PhantomData
}
}
pub fn as_ptr(&self) -> *const T {
self.base
}
pub fn as_mut_ptr(&mut self) -> *mut T {
self.base
}
pub fn as_slice(&self) -> &'a [T] {
unsafe {
slice::from_raw_parts(self.base, self.len)
}
}
pub fn as_mut_slice(&mut self) -> &'a mut [T] {
unsafe {
slice::from_raw_parts_mut(self.base, self.len)
}
}
pub fn len(&self) -> usize {
self.len
}
}
impl<'a, T> AsRef<[T]> for CMutSlice<'a, T> {
fn as_ref(&self) -> &[T] {
unsafe {
slice::from_raw_parts(self.base, self.len)
}
}
}
impl<'a, T> AsMut<[T]> for CMutSlice<'a, T> {
fn as_mut(&mut self) -> &mut [T] {
unsafe {
slice::from_raw_parts_mut(self.base, self.len)
}
}
}
unsafe impl<'a, T: Sync> Sync for CSlice<'a, T> { }
unsafe impl<'a, T: Sync> Send for CSlice<'a, T> { }
unsafe impl<'a, T: Sync> Sync for CMutSlice<'a, T> { }
unsafe impl<'a, T: Send> Send for CMutSlice<'a, T> { }
impl<'a, T> Index<usize> for CSlice<'a, T> {
type Output = T;
fn index(&self, i: usize) -> &T {
self.as_ref().index(i)
}
}
impl<'a, T> Index<usize> for CMutSlice<'a, T> {
type Output = T;
fn index(&self, i: usize) -> &T {
self.as_ref().index(i)
}
}
impl<'a, T> IndexMut<usize> for CMutSlice<'a, T> {
fn index_mut(&mut self, i: usize) -> &mut T {
self.as_mut().index_mut(i)
}
}
pub trait AsCSlice<'a, T> {
fn as_c_slice(&'a self) -> CSlice<'a, T>;
}
pub trait AsCMutSlice<'a, T> {
fn as_c_mut_slice(&'a mut self) -> CMutSlice<'a, T>;
}
impl<'a> AsCSlice<'a, u8> for str {
fn as_c_slice(&'a self) -> CSlice<'a, u8> {
CSlice {
base: self.as_ptr(),
len: self.len(),
marker: PhantomData
}
}
}
impl<'a, T> AsCSlice<'a, T> for [T] {
fn as_c_slice(&'a self) -> CSlice<'a, T> {
CSlice {
base: self.as_ptr(),
len: self.len(),
marker: PhantomData
}
}
}
impl<'a, T> AsCMutSlice<'a, T> for [T] {
fn as_c_mut_slice(&'a mut self) -> CMutSlice<'a, T> {
CMutSlice {
base: self.as_mut_ptr(),
len: self.len(),
marker: PhantomData
}
}
}