extern crate libc;
use array::Array;
use defines::AfError;
use error::HANDLE_ERROR;
use seq::Seq;
use self::libc::{c_double, c_int, c_uint};
use util::{AfArray, AfIndex, DimT, MutAfArray, MutAfIndex};
use std::marker::PhantomData;
#[allow(dead_code)]
extern {
fn af_create_indexers(indexers: MutAfIndex) -> c_int;
fn af_set_array_indexer(indexer: AfIndex, idx: AfArray, dim: DimT) -> c_int;
fn af_set_seq_indexer(indexer: AfIndex, idx: *const SeqInternal, dim: DimT, is_batch: c_int) -> c_int;
fn af_release_indexers(indexers: AfIndex) -> c_int;
fn af_index(out: MutAfArray, input: AfArray, ndims: c_uint, index: *const SeqInternal) -> c_int;
fn af_lookup(out: MutAfArray, arr: AfArray, indices: AfArray, dim: c_uint) -> c_int;
fn af_assign_seq(out: MutAfArray, lhs: AfArray, ndims: c_uint, indices: *const SeqInternal, rhs: AfArray) -> c_int;
fn af_index_gen(out: MutAfArray, input: AfArray, ndims: DimT, indices: AfIndex) -> c_int;
fn af_assign_gen(out: MutAfArray, lhs: AfArray, ndims: DimT, indices: AfIndex, rhs: AfArray) -> c_int;
}
pub struct Indexer<'object> {
handle: i64,
count: usize,
marker: PhantomData<&'object ()>,
}
pub trait Indexable {
fn set(&self, idxr: &mut Indexer, dim: u32, is_batch: Option<bool>);
}
impl Indexable for Array {
#[allow(unused_variables)]
fn set(&self, idxr: &mut Indexer, dim: u32, is_batch: Option<bool>) {
unsafe {
let err_val = af_set_array_indexer(idxr.get() as AfIndex, self.get() as AfArray,
dim as DimT);
HANDLE_ERROR(AfError::from(err_val));
}
}
}
impl<T: Copy> Indexable for Seq<T> where c_double: From<T> {
fn set(&self, idxr: &mut Indexer, dim: u32, is_batch: Option<bool>) {
unsafe {
let err_val = af_set_seq_indexer(idxr.get() as AfIndex,
&SeqInternal::from_seq(self) as *const SeqInternal,
dim as DimT, is_batch.unwrap() as c_int);
HANDLE_ERROR(AfError::from(err_val));
}
}
}
impl<'object> Indexer<'object> {
#[allow(unused_mut)]
pub fn new() -> Indexer<'object> {
unsafe {
let mut temp: i64 = 0;
let err_val = af_create_indexers(&mut temp as MutAfIndex);
HANDLE_ERROR(AfError::from(err_val));
Indexer{handle: temp, count: 0, marker: PhantomData}
}
}
pub fn set_index<'s, T>(&'s mut self, idx: &'object T, dim: u32, is_batch: Option<bool>)
where T : Indexable + 'object {
idx.set(self, dim, is_batch);
self.count = self.count+1;
}
pub fn len(&self) -> usize {
self.count
}
pub fn get(&self) -> i64 {
self.handle
}
}
impl<'object> Drop for Indexer<'object> {
fn drop(&mut self) {
unsafe {
let ret_val = af_release_indexers(self.handle as AfIndex);
match ret_val {
0 => (),
_ => panic!("Failed to release indexers resource: {}", ret_val),
}
}
}
}
pub fn index<T: Copy>(input: &Array, seqs: &[Seq<T>]) -> Array
where c_double: From<T>
{
unsafe {
let mut temp: i64 = 0;
let seqs: Vec<SeqInternal> = seqs.iter().map(|s| SeqInternal::from_seq(s)).collect();
let err_val = af_index(&mut temp as MutAfArray
, input.get() as AfArray, seqs.len() as u32
, seqs.as_ptr() as *const SeqInternal);
HANDLE_ERROR(AfError::from(err_val));
Array::from(temp)
}
}
#[allow(dead_code)]
pub fn row(input: &Array, row_num: u64) -> Array {
index(input, &[Seq::new(row_num as f64, row_num as f64, 1.0),
Seq::default()])
}
#[allow(dead_code)]
pub fn set_row(input: &Array, new_row: &Array, row_num: u64) -> Array {
assign_seq(input,
&[Seq::new(row_num as f64, row_num as f64, 1.0), Seq::default()],
new_row)
}
#[allow(dead_code)]
pub fn rows(input: &Array, first: u64, last: u64) -> Array {
index(input, &[Seq::new(first as f64, last as f64, 1.0), Seq::default()])
}
#[allow(dead_code)]
pub fn set_rows(input: &Array, new_rows: &Array, first: u64, last: u64) -> Array {
assign_seq(input, &[Seq::new(first as f64, last as f64, 1.0), Seq::default()], new_rows)
}
#[allow(dead_code)]
pub fn col(input: &Array, col_num: u64) -> Array {
index(input, &[Seq::default(), Seq::new(col_num as f64, col_num as f64, 1.0)])
}
#[allow(dead_code)]
pub fn set_col(input: &Array, new_col: &Array, col_num: u64) -> Array {
assign_seq(input,
&[Seq::default(), Seq::new(col_num as f64, col_num as f64, 1.0)],
new_col)
}
#[allow(dead_code)]
pub fn cols(input: &Array, first: u64, last: u64) -> Array {
index(input, &[Seq::default(), Seq::new(first as f64, last as f64, 1.0)])
}
#[allow(dead_code)]
pub fn set_cols(input: &Array, new_cols: &Array, first: u64, last: u64) -> Array {
assign_seq(input, &[Seq::default(), Seq::new(first as f64, last as f64, 1.0)], new_cols)
}
#[allow(dead_code)]
pub fn slice(input: &Array, slice_num: u64) -> Array {
index(input,
&[Seq::default(), Seq::default(), Seq::new(slice_num as f64, slice_num as f64, 1.0)])
}
#[allow(dead_code)]
pub fn set_slice(input: &Array, new_slice: &Array, slice_num: u64) -> Array {
assign_seq(input,
&[Seq::default(), Seq::default(), Seq::new(slice_num as f64, slice_num as f64, 1.0)],
new_slice)
}
#[allow(dead_code)]
pub fn slices(input: &Array, first: u64, last: u64) -> Array {
index(input,
&[Seq::default(), Seq::default(), Seq::new(first as f64, last as f64, 1.0)])
}
#[allow(dead_code)]
pub fn set_slices(input: &Array, new_slices: &Array, first: u64, last: u64) -> Array {
assign_seq(input,
&[Seq::default() , Seq::default(), Seq::new(first as f64, last as f64, 1.0)],
new_slices)
}
pub fn lookup(input: &Array, indices: &Array, seq_dim: i32) -> Array {
unsafe {
let mut temp: i64 = 0;
let err_val = af_lookup(&mut temp as MutAfArray, input.get() as AfArray,
indices.get() as AfArray, seq_dim as c_uint);
HANDLE_ERROR(AfError::from(err_val));
Array::from(temp)
}
}
pub fn assign_seq<T: Copy>(lhs: &Array, seqs: &[Seq<T>], rhs: &Array) -> Array
where c_double: From<T>
{
unsafe{
let mut temp: i64 = 0;
let seqs: Vec<SeqInternal> = seqs.iter().map(|s| SeqInternal::from_seq(s)).collect();
let err_val = af_assign_seq(&mut temp as MutAfArray, lhs.get() as AfArray,
seqs.len() as c_uint, seqs.as_ptr() as *const SeqInternal,
rhs.get() as AfArray);
HANDLE_ERROR(AfError::from(err_val));
Array::from(temp)
}
}
pub fn index_gen(input: &Array, indices: Indexer) -> Array {
unsafe{
let mut temp: i64 = 0;
let err_val = af_index_gen(&mut temp as MutAfArray, input.get() as AfArray,
indices.len() as DimT, indices.get() as AfIndex);
HANDLE_ERROR(AfError::from(err_val));
Array::from(temp)
}
}
pub fn assign_gen(lhs: &Array, indices: &Indexer, rhs: &Array) -> Array {
unsafe{
let mut temp: i64 = 0;
let err_val = af_assign_gen(&mut temp as MutAfArray, lhs.get() as AfArray,
indices.len() as DimT, indices.get() as AfIndex,
rhs.get() as AfArray);
HANDLE_ERROR(AfError::from(err_val));
Array::from(temp)
}
}
#[repr(C)]
struct SeqInternal {
begin: c_double,
end: c_double,
step: c_double,
}
impl SeqInternal {
fn from_seq<T: Copy>(s: &Seq<T>) -> Self where c_double: From<T> {
SeqInternal {
begin: From::from(s.begin()),
end: From::from(s.end()),
step: From::from(s.step()),
}
}
}